We will need to know how to do this when we make our first C++ class,
class
date
.
theTime.C
,
theTime.txt
.
tm_sec
might be a leap second.)
time
function is the number of seconds that have elapsed
since the ever-memorable night they invented Unix
(the original version of Linux),
midnight on January 1, 1970.
That’s about 55 and a half years ago.
bc -l (minus lowercase L for the math library of the "binary calculator") 1749005228 / (60 * 60 * 24 * 365.25) 55.42263125205972570791 control-dThe function
localtime
fills up a structure with information,
and returns a pointer to this structure.
(tm_sec
might be a leap second.)
Pass some information
(the
int
s
year
,
month
,
day
)
down to the functions
(print
,
next
,
etc.)
that do all the work.
3ints.C
,
3ints.txt
.
int
s.
struct.C
,
struct.txt
.
struct
.
obj1.C
,
obj1.txt
.
obj2.C
,
obj2.txt
.
date::next
and the four-argument
(date::next
).
The constructor whose argument is a
const date&
is called the
copy constructor.
main
function tried to create a
date d {2, 30, 2025}; //Bad date: there is no February 30Is the exception caught in the
main
function of
obj2.C
?
See
new3.C
for a previous example of catching an exception.
date
in
obj2.C
.
Even if we don’t write this constructor,
the computer will still behave as if we had.
date
.
This constructor will have no explicit arguments (i.e., arguments you can see),
and will initialize the newborn
date
object to today’s date.
A constructor with no expicit arguments is called a
default
constructor.
The default constructor for class
date
will have to call the functions
time
and
localtime
,
so
obj2.C
will have to include the header file
ctime
.
Test the default constructor by changing the declaration for
today
in the
main
function of
obj2.C
to
const date today; //Call the default constructor.
const
member functions for the class date
in obj2.C
named
prev
and
prev
.
They will be just like the existing member functions
next
and
next
,
except that they will move the
date
object into the past instead of the future.
Test the new member functions by calling them in
main
.
int
:
//Bad. int i; //Initialize i to unpredictable garbage. i = 10; //Assign a value to i, replacing the garbage.
//Better. int i {10}; //Initialize i to 10.Now with data members in a constructor:
//Bad. //This constructor for class date initializes the three data members of the //newborn object to unpredictable garbage. Then it assigns values to the //data members, replacing the garbage. //Error checking omitted for brevity. date::date(int init_month, int init_day, int init_year) { year = init_year; month = init_month; day = init_day; }
//Better. //This constructor for class date initializes the three data members of the //newborn object to the values supplied by the user, init_year, init_month, //init_day. //Error checking omitted for brevity. date::date(int init_month, int init_day, int init_year) : year {init_year}, month {init_month}, day {init_day} { //These curly braces are empty. //Other than initializing the three data members, this constructor has //no work to do (because we have omitted error checking). }
obj3.C
,
obj3.txt
.
date
initializes the data members of the newborn
date
object,
instead of filling them with unpredictable garbage and then assigning to them.
mkdir
to make the directory.
(This new directory will have to be a sub-directory, or a sub-sub-directory,
or a sub-sub-sub-directory, etc., of your home directory on
storm.cis.fordham.edu
.)
#include
with
<
angle brackets>
looks in the directory
/usr/include/c++/15
for the header file
(on our machine
storm.cis.fordham.edu
).
#include
with
"
double quotes"
looks in your current directory for the header file.
date.h
is the
header file
for class
date
.
It contains the blueprint for the class.
See the
explanation
for the
#
lines at the start and end of this file.
date.C
is the
implementation file
for class
date
.
It contains the definitions for the static data members,
member functions,
and
friend functions
of the class.
It includes
date.h
.
main.C
,
main.txt
contains the rest of the C++ program that uses objects of class
date
.
It includes
date.h
.
c++ main.C date.C ls -l a.out ./a.out
date.h
,
the same header file as abovedate.C
,
the same implementation file as abovemain2.C
,
main2.txt
,
a different main filec++ main2.C date.C ls -l a.out ./a.out
The data members are private,
so no one other than the member functions of class
date
needs to know that the data members have changed.
Do not change the three arguments of the constructor,
or the output of the
print
member function,
even though the class no longer has three data members.
date
with two data members,
year
and
day
.
date
with one data member,
day
.
distance
function
to the one-data-member class
date
.
Like a
date
object,
we can think of a
point
object primarily as a structure that holds data members.
c++ main.C point.C ls -l a.out ./a.out
point
a static data member named
origin
of type
const point
.
(See
date.h
and
date.C
for the declaration and definition of a static data member.)
Then change the body of the
r
member function to
//return sqrt(x * x + y * y); return distance(*this, origin); //distance from this point to the origin
date
and
point
,
an object of class
announcer
holds very little data: just a name for itself.
The purpose of an
announcer
object is not to hold data.
Its purpose is to output a birth announcement and a death announcement
at the start and end of its life.
New features:
announcer
has a static member function named
howMany
,
that receives no invisible pointer.
A static member function is similar to a “friend
function”;
we’ll have to talk about their difference later.
announcer
because the copy constructor I’d get by default would do no more
than initialize the non-static
data member:
announcer::announcer(const announcer& another) //"copy constructor" : name {another.name} { }
c++ main.C announcer.C ls -l a.out ./a.out
Exercise.
Have the constructors and destructor for class
announcer
indent their output by the current value (or twice the current value) of
announcer::count
spaces.
In the above program,
for example,
Ann’s birth and death announcements would be indented 7 spaces.
See
main2.txt
.
new
and
delete[]
a block of memory in C++
(a typical resource)constructor.c
.
An old fashioned C program with a pair of explicit function calls, to
fopen
and
fclose
.
It would be bad if you forgot one of these calls,
or called them in the wrong order,
or called one of them twice.
cc
instead of
c++
.
cc constructor.c (Should create a file named a.out) ls -l a.out -rwxr-xr-x. 1 jsmith students 25048 Jun 1 09:18 a.out ./a.out (Should create a file named outfile.txt) echo $? (See the exit status producted by a.out) 0 ls -l outfile.txt -rw-r--r--. 1 jsmith students 16 Jun 1 09:26 outfile.txt cat outfile.txt (See what's in the file outfile.txt) Hello. Goodbye. rm outfile.txt
constructor.C
.
A C++ program that constructs and destructs an object,
instead of making a pair of explicit function calls.
This program outputs the same outfile.txt
file as the above program.
#include <iostream> #include <cstdlib> using namespace std; int main() { window w; //Construct window w. icon i0 {&w}; //Construct icon i0 and put it in the window. icon i1 {&w}; //Construct icon i1 and put it in the window. icon i2 {&w}; //Construct icon i2 and put it in the window. doWork(); return EXIT_SUCCESS; //Destruct i2, i1, i0, w in that order. }
element
.
{
curly
braces}
.
We saw a dynamically allocated block that holds an array
here.
c++ main.C announcer.C ls -l a.out ./a.out
interval
)
containing two smaller objects
(date
s)
as its data members.
The constructor for class
interval
begins by automatically making two detours to the constructor for class
date
.
After these detours,
the
{
body}
of the constructor for class
interval
is executed.
Similarly, the destructor for class
interval
automatically ends by calling
the destructors for the two
date
objects inside of the
interval
object that is dying.
class date { int year; int month; int day; public: date(int m, int d, int y); }; class interval { date begin; date end; public: interval(int m1, int d1, int y1, int m2, int d2, int y2); //6 arguments }; //Definition of the constructor for class interval. interval::interval(int m1, int d1, int y1, int m2, int d2, int y2) : begin {m1, d1, y1}, end {m2, d2, y2} { //the body of the constructor for class interval } //Definition of the constructor for class date. date::date(int m, int d, int y) : year {y}, month {m}, day {d} { //the body of the constructor for class date }
stack
object is hardwired to hold a stack of
int
s.
A stack
is what an accountant would call a LIFO list:
“last in, first out”.
Compile and run this three-file program (consisting of
stack.h
,
stack.C
,
and
main.C
)
with
c++ main.C stack.C ls -l a.out ./a.out
stack.C
,
stack.txt
.
stack
,
like the template class
vector
we saw
here.
Write the name of the data type of your choice in the
<
angle
brackets>
.
On our machine storm.cis.fordham.edu
,
an int
occupies 4 bytes = 32 bits.
Therefore an
int
can hold any one of
232 = 4,294,967,296
different values.
We let these values represent integers in the range from
–2,147,483,648
to
2,147,483,647 inclusive.
The leftmost bit of an
int
is called the
sign bit.
It is
1
for negative numbers,
0
for non-negative numbers.
bits | int |
01111111 11111111 11111111 11111111 |
2,147,483,647 |
01111111 11111111 11111111 11111110 |
2,147,483,646 |
01111111 11111111 11111111 11111101 |
2,147,483,645 |
⋮ | ⋮ |
00000000 00000000 00000000 00000010 |
2 |
00000000 00000000 00000000 00000001 |
1 |
00000000 00000000 00000000 00000000 |
0 |
11111111 11111111 11111111 11111111 |
–1 |
11111111 11111111 11111111 11111110 |
–2 |
11111111 11111111 11111111 11111101 |
–3 |
⋮ | ⋮ |
10000000 00000000 00000000 00000010 |
–2,147,483,646 |
10000000 00000000 00000000 00000001 |
–2,147,483,647 |
10000000 00000000 00000000 00000000 |
–2,147,483,648 |
On our machine storm.cis.fordham.edu
,
an unsigned int
occupies 4 bytes = 32 bits.
Therefore an
unsigned int
can hold any one of
232 = 4,294,967,296
different values.
We let these values represent integers in the range from
0
to
4,294,967,295 inclusive.
bits | unsigned int |
11111111 11111111 11111111 11111111 |
4,294,967,295 |
11111111 11111111 11111111 11111110 |
4,294,967,294 |
11111111 11111111 11111111 11111101 |
4,294,967,293 |
⋮ | ⋮ |
00000000 00000000 00000000 00000010 |
2 |
00000000 00000000 00000000 00000001 |
1 |
00000000 00000000 00000000 00000000 |
0 |
The member function
myrandom::rand
in the file
myrandom.C
scrambles the value of the data member
myrandom::next
with a multiplication and an addition.
For example, the first time we call
myrandom::random
,
it changes the value of
next
from 1 to
1,103,527,590.
Mathematicians have determined that the most random part
of the resulting value
consists of the 15 bits in positions 16 through 30 inclusive.
Here is 1,103,527,590 written in binary with these bits
in yellow:
01000001110001100111111010100110
(this is 1,103,527,590)
00000000000000000100000111000110
(this is 1,103,527,590 shifted 16 places to the right)
& 00000000000000000111111111111111
(this mask is 0x7FFF
)
00000000000000000100000111000110
(this is 16,838)
The result of the “bitwise and” is
100000111000110
which is 16,838 in decimal.
myrandom
object does only one thing for us.
In other words,
it has only one member function,
not counting the constructor.