SlideShare a Scribd company logo
1 of 63
Wednesday, Jan 11
Collect Academic Integrity Forms
Constructors
Destructors
Class Composition
Composition with Initializer Lists
A few final topics required for
Project #1
• Learning how to use the VC
debugger (time permitting)
•
•
•
•
•
•

th
Constructors: Class Initialization

Every class should have
an initialization function
that can be used to
reset new variables
before they’re used.

class CSNerd
{
public:
void Init(int PCs, bool usesMac)
{
2 false
m_numPCs = PCs; // # of PCs owned
void Init(int PCs, bool usesMac)
Ack! How can
david {
m_macUser = usesMac;
m_numPCs = PCs;
m_macUser = usesMac;
}
someone have -32
}

computers?
10*2 = 20 int

int getNerdScore(void)
{
if(m_macUser == true)
return(0);
return(10 * m_numPCs);
}
m_numPCs

-32

m_macUser

getNerdScore(void)

{

false

if(m_macUser == true)
return(0); //not nerdy; “artistic”
return(10 * m_numPCs);

}
main()
{
private:
CSNerd david;
int m_numPCs;
Right! Our programmer might
But all simple variables
Well, remember, there’s one problem
david.Init(2,false); // geeky So if you forget to call the Init
bool m_macUser;
forget with such anInit
to call the Init
(e.g., ints, bools, CSNerd’s member
cout << david.getNerdScore(); function, your etc.) in C++ start out
};
function before values. Not
variables will have randomusing is it?
}
with random function… What the
values unless they’re

what you’d want.
variable…Here’s ahappen?
explicitly What’ll hint!
initialized!
class CSNerd
{
public:
void Init(int PCs, bool usesMac)
{
m_numPCs = PCs;
m_macUser = usesMac;
}
int getNerdScore(void)
{
if(m_macUser == true)
return(0);
return(10 * m_numPCs);
}
private:
int m_numPCs;
bool m_macUser;
};

Constructors
Wouldn’t it be great if C+
+ would guarantee that
every time we create a
new class variable, it’ll be
auto-initialized?
Well, as it turns out, that’s
exactly what the C++
constructor does!

main()
{
CSNerd david;
cout << david.getNerdScore();
}
class CSNerd
Since the constructor is
{
called automatically any time
public:
you
void Init(int define bool usesMac)
CSNerd (int PCs, a new variable…
{
m_numPCsthere’s no chance of a new
= PCs;
variable being
m_macUser = usesMac; uninitialized
accidentally.
}
int getNerdScore(void)
{
if(m_macUser == true)
return(0);
return(10 * m_numPCs);
}
private:
int m_numPCs;
bool m_macUser;
};

Constructors
main()
{
(3,true);
CSNerd chen;3 true
chen.Init(3,true);
cout <<
chen.getNerdScore();
}

true
3
Instead constructor is
The of being called
CSNerd(int
chen called PCs, bool usesMac)
{
Init, the=automatically
constructor
m_numPCs
PCs;
m_macUser = usesMac;
functiontime the same
}
every has you create
int getNerdScore(void)
name as the class!
{ a new instance of
if(m_macUser ==
(Confusing, true)
huh?)
return(0);

your class.

return(10 * m_numPCs);
}

m_numPCs

m_macUser

A constructor is a special member function that automatically
initializes every new variable you create of that class.
And remember to also
include just the function
header, followed by a
class CSNerd semicolon, in the class
{
declaration itself.

Constructors

class CSNerd
public:
{
CSNerd(int PCs, bool usesMac);
public:
{
CSNerd(int PCs, bool usesMac)
m_numPCs Boy, isn’t that syntax ugly?
= PCs;
{
m_macUser = usesMac;
m_numPCs = PCs;
Just remember, to define
}
m_macUser = usesMac;
...
a constructor outside the
} return(true); //illegal!
class declaration:
}
private:
...
private:
int m_numPCs;
bool m_macUser;
};

int m_numPCs;use the class name,
bool m_macUser; by ::, followed by
followed
};
the class name.
CSNerd::

You can define the
LikeconstructorA theno return is a special
constructor
To summarize…inhas class
constructor type! It’s not
The all other member functions, the
declaration (see not void, int, have new
constructor’sit’s above)…be defined inside
function in your logic can initializes athe
The constructor function
allowed! Notice class thatMUST or bool. Or, outside the class
variable whennot first created.
SAME NAME AS class to return a value.
or outside the alloweddeclaration. declaration, like this…
And thus it’s its THE CLASS!
Constructors

If a constructor
requires parameters:

class CSNerd
{
public:
CSNerd(int PCs, bool usesMac )
{
m_numPCs = PCs;
0;
m_macUser = usesMac;
false;
}
int getNerdScore(void)
{
if(m_macUser == true)
return(0);
return(10 * m_numPCs);
}
private:
int m_numPCs;
bool m_macUser;
};

You must to provide
values for those
parameters when you
create a new variable:

main()
{
CSNerd ed(1,true); // OK
ed(1,true);//invalid!
CSNerd alan; // invalid!
OK!
}
Constructors
class CSNerd
{
public:
CSNerd(int PCs, bool usesMac = true )
{
m_numPCs = PCs;
m_macUser = usesMac;
}
int getNerdScore(void)
{
if(m_macUser == true)
return(0);
return(10 * m_numPCs);
}
private:
int m_numPCs;
bool m_macUser;
};

Just like any C++
function, a constructor
can have one or more
default parameters…
main()
{
1 false
CSNerd lyn(1,false);
5
CSNerd ned(5); // OK!
CSNerd dave; //invalid!
cout <<
lyn.getNerdScore();
}
C++: “I’m confused! Should I call this
class CSNerd
constructor with default parameters…”
{
public:
CSNerd(int PCs, bool usesMac = true)
CSNerd()
CSNerd(int PCs=1, bool usesMac=true) Your class can have many
{
different constructors.
C++:
m_numPCs = PCs;
m_numPCs = 1; “…or should I call this
(this is called overloading
m_macUser = false;
= usesMac;
constructor with no parameters?”
m_macUser
constructors)
}
main()
int getNerdScore(void)
{
{

Constructors

if(m_macUser == true)
return(0);
return(10 * m_numPCs);
}

CSNerd lyn(1,false);
CSNerd ned(5); // OK!
CSNerd dave; // OK!!!
//invalid!
cout <<
lyn.getNerdScore();
}

private:
int m_numPCs;
bool m_macUser;
};

One more thing: If you have
2 or more constructors, they
cannot have the exact same
parameters/types.
Constructors
If you don’t define any
constructors at all…

class CSNerd
{
public:

then C++ will provide an
implicit, default
constructor for you that
basically does nothing!

int getNerdScore(void) by compiler
CSNerd() // generated
{
if(m_macUser == true)
// I do nothing at all.
//return(0);
I’m not worthy!!!!!
} return(10 * m_numPCs);
}
private:
int m_numPCs;
bool m_macUser;
};

main()
{
CSNerd carey; // OK

}

cout <<
carey.getNerdScore(); //??

In this case, your
member variables are
never initialized.
Constructors & Arrays
class CSNerd
{
public:
CSNerd(int PCs, bool usesMac = true)
{
m_numPCs = PCs;
m_macUser = usesMac;
}

1
false
1
false
1
false
1
false

CSNerd()
{
m_numPCs = 1;
m_macUser = false;
}
...
private:
int m_numPCs;
bool m_macUser;
When you define an array, the your class,
If you want to have an array of
};

constructor is run on every
your class must have a constuctor that
element in the no arguments!
requires array!

main()
{
CSNerd lec1[4];
cout <<
lec1[0].getNerdScore();

}
Constructors
There are several different ways to initialize your member
variables in a constructor. Here’s the easiest way:
class CSNerd
{
public:
CSNerd(int PCs, bool usesMac)
{
m_numPCs = PCs;
Class CSNerd
m_macUser = usesMac;
{
}
public:
...

Or, if you’re really
masochistic, you
can do a little of
both.

Here’s a more complex way
that does the same thing…

This is called an
“initializer list”

CSNerd(int PCs, bool usesMac)
{

: m_numPCs (PCs) , m_macUser (usesMac)

}
...

// I don’t need to do anything!
m_macUser = usesMac;
Constructor Challenge
class CSProf
{
public:
// version #4
#3
#2
#1
39)
CSProf(const string &name, int age = 39);
{ : m_name(name), m_age(age)
{ m_name = name;
// do nothing else
m_age = age;
}

Define a constructor
that initializes a CSProf.
The user can specify the
name of the prof and
his/her age.

Notice youIf the user omits the
don’t put theage, then the prof’s
default age is 39.
“= 39” here too!

...
private:
string m_name;
int m_age;
};
// version #2
#4
CSProf::CSProf(const string &name, int age)
{ : m_name(name), m_age(age)
{ m_name = name;
// do nothing else
m_age = age;
}

int main(void)
{
CSProf a(“David”,52);
CSProf b(“Carey”);
}
When Constructors are Called
A constructor is called any time you create a
new variable for a class.
A constructor is called N times when you create
an array of size N.
A constructor is called when you use new to dynamically
allocate a new variable or an array. (we’ll learn new later)
The constructor is not called when you just
define a pointer variable.

main()
{
CSNerd carey(3,false), bill; // called once for each var
CSNerd arr[52];

// constructor’s called 52 times

CSNerd *ptr = new CSNerd(1,3); // c’tor called once
CSNerd *dyn = new CSNerd[6];
// c’tor called 6 times
CSNerd *justAPtr; // c’tor is NOT called
Class Challenge
Name all the times the CSNerd constructor is called in
this example…

class CSNerd
{
public:
CSNerd()
{
m_numPCs = 1;
m_macUser = true;
}
...
private:
int m_numPCs;
bool m_macUser;
};

void foo()
{
CSNerd *herbert = new CSNerd;
}
void main(void)
{
int j;
CSNerd *ptrToNerd;
CSNerd xavier;
for (j=0;j<3;j++)
{
CSNerd a[5];
foo();
}
}
Destructors
Just as every class has a constructor, every class also has a
destructor function (one and only one of these).
The job of the destructor is to de-initialize or destruct each
variable of a class when the variable goes away.
Destructors return nothing and take NO parameters.
class SomeClass
{
public:
SomeClass();
//
~SomeClass()
~SomeClass();
//
{
private:
//
... destructor code
//
}; }
private:
SomeClass::~SomeClass()
...
//
{
};
// destructor code
}

constructor
destructor!
whatever
whatever

To define a d’tor function,
you use the
tilde ~ character in front
of the class’s name:
Or define the destructor
function outside your
class…
and just add a function
header inside the class
declaration.
Ben’s
Balance:
$990
$1290
$1270
$1280
$1260
$1000
PayPerUseBank.com

(we charge by the minute!)

Ben we need a Destructor?
Why doDover
CSRules

Here we have a class that
allows ib disappears banking.
Hmmm… us to do internetwhen

$300
CSRules
Ben Dover
Let’s see but the user
main exits,what happens when
class InternetBanking
Wow – we just logged
we use this class without a
forgot to call stopBanking,
{
destructor.
public:on and they’re
so our PC is still connected
voidalready charging
startBanking(string nm,string pw)
Of course, had we added
to (and being charged by) a
{
fees!
m_ic.connect(“payperusebank.com”);
destructor… None of this
the bank!
m_ic.send(nm); // send name
m_ic.send(pw); // send password

}

would have happened…

int main(void)

void stopBanking(){ m_ic.disconnect(); }
{
Now, when ourib
ib
void deposit(float amount) { … }
InternetBanking ib;
variable goes away,
~InternetBanking()
C++ will automatically
{
string name, pw;
m_ic.disconnect();
cin >> name >> pw;
call it’s destructor!!!
}
ib.startBanking(name,pw);
private:
ib.deposit(300);
InternetConnection m_ic;
}
};
When must you have a destructor?
Any time a class…
Allocates data using the new command
Opens a disk file
Opens a network connection
Your class must have a destructor that…
Frees the allocated memory
Closes the disk file
Disconnects the network connection
Don’t forget or you’ll FAIL!
Destructors
So when is a destructor called anyway?
Local function variables are destructed any time a function exits.
Local variables defined in a block are destructed when the block finishes.
Dynamically allocated variables are destructed when delete is called
before the memory is actually freed by the operating system.
void Dingleberry(void)
{
SomeClass c;

Oh, and what about arrays?

When an array goes
away, the destructor is
called for every item in the
array (just like construction).

for (int j=0;j<10;j++)
{
SomeClass v;
// do something
}
v’s destructor is called each time we hit the end of the block
InternetBanking *ib = new InternetBanking(“Carey”,”MyPassword”);
// do something
delete ib;
The d’tor is called for ib by C++ here
c’s destructor is called.
}
Class Challenge #2
Name all the times the CSNerd destructor is called in
this example…
class CSNerd
{
public:
CSNerd()
{
m_numPCs = 1;
m_macUser = true;
}
~CSNerd()
{

void foo()
{
CSNerd a, *b;
}
Question: How could we make
our program more efficient?
void main(void) where this is
(Hint: Look
{
pointing)
int j;
CSNerd *ptr, x;
ptr = new CSNerd;
for (j=0;j<3;j++)
{
CSNerd a[5];
foo();
}
delete ptr;

cout <<“Argh! I’m dying. Where’s my
iphone?”;

}
...
private:
int m_numPCs;
bool m_macUser;

}
Can you guess?
Programming Language Inventor
Or
Serial Killer
See if you can guess who uses a keyboard and
who uses a chainsaw!
Class Composition
Class composition: If a class contains one or more classes
as member variables, then you are using class composition:
class Valve

class GasTank
{
…
};
class Car
{
...
private:
GasTank myTank;
};

{

…
};

Class Composition
Class Composition

Class Composition

class Heart
{
…

};

private:
Valve m_valves[4];

class TinMan
{

...
private:
Heart m_myHeart;
};
class Stomach
{

public:

Stomach() { gas = 0; }
~Stomach() { cout << “boom!”; }
void eat() { cout << “yummy”; gas ++; }
void fart() { gas--; cout << “pffft!”; }

private:

};

int gas;

class Nerd
{

public:
Nerd() { thought=“Waaa”; belly.eat(); }
void meetCuteGirl(string &herName)
{

}

thought = “H.O.T. HOT!”;
belly.fart();

~Nerd() { thought=“Argh”; belly.eat( ); }
private:
string thought;
Stomach belly;
};

Composition

In this example, our Nerd
class holds a Stomach variable
(every nerd has a stomach)
When using composition, the
outer class (Nerd) can use all of
the public functions of the
contained variable (belly) in:
• The outer class’s constructor(s)
• The outer class’s functions
• The outer class’s destructor

Ok, that was easy… But now
let’s look into how
construction and destruction
work with composition…
class Stomach
{

public:

Stomach() { gas = 0; }
~Stomach() { cout << “boom!”; }
void eat() { cout << “yummy”; gas ++; }
void fart() { gas--; cout << “pffft!”; }

private:
};

int gas;

Composition and
Construction
When we create a Stomach
variable, its constructor is
called.
And when the variable goes
away, its destructor is called…

s
gas
int main(void)
{
Stomach
s;
... // use s
}

boom!

0
class Stomach
{

public:

Stomach() { gas = 0; }
~Stomach() { cout << “boom!”; }
void eat() { cout << “yummy”; gas ++; }
Hint:
void fart() { gas--; cout << “pffft!”; }

private:
};

int gas;

class Nerd
{

When we
How can Nerd’screate a Nerd
variable, belly
constructor use the Nerd’s constructor
variable if belly must be called.
hasn’t
been constructed?
But our Nerd contains a
Stomach, so its constructor
must be called too!

public:
Nerd() { thought=“Waaa”; belly.eat( ); }
void meetCuteGirl(string &herName)
{

}

So which constructor is called
first? Nerd’s or Stomach’s?

thought = “H.O.T. HOT!”;
belly.fart();

~Nerd() { thought=“Argh”; belly.eat(); }
private:
string thought;
Stomach belly;
};

Composition and
Construction

int main(void)
{
Nerd
david;
...
}
class Stomach
{

public:

Composition and
Since theConstruction
Stomach was

Stomach() { gas = 0; }
~Stomach() { cout << “boom!”; }
C++ constructs the
void eat() { cout << “yummy”; gasalready constructed, our
++; }
contained class
void fart() { gas--; cout << “pffft!”; } class can use it in its first,
Nerd

private:
};

int gas;

class Nerd
{

public:
Nerd() { thought=“Waaa”; belly.eat( ); }
void meetCuteGirl(string &herName)
{

}

thought = “H.O.T. HOT!”;
belly.fart();

~Nerd() { thought=“Argh”; belly.eat(); }
private:
string thought;
Stomach belly;
};

and the outer class second.
constructor!

So our Stomach is constructed
first and then Nerd is
constructed after.

david

thought “Waaa”

belly
gas
int main(void)
{
Nerd
david;
...
}

1
0

yummy!
class Stomach
{

public:

Stomach() { gas = 0; }
~Stomach() { cout << “boom!”; }
void eat() { cout << “yummy”; gas ++; }
void fart() { gas--; cout << “pffft!”; }

private:
};

int gas;

class Nerd
{

public:
Nerd()

}

thought = “H.O.T. HOT!”;
belly.fart();

~Nerd() { thought=“Argh”; belly.eat(); }
private:
string thought;
Stomach belly;
};

Now what happens when our
Nerd is destructed?

Destruction happens in the reverse
order. The outside destructor
runs first, then the contained
destructor runs second.
the Stomach has not

Since
been destructed yet, it
{ thought=“Waaa”; belly.eat( ); still bedavid by Nerd!
can }
used thought “Waaa”
“Argh”

void meetCuteGirl(string &herName)
{

Composition and
Destruction

belly

int main(void)
{
Nerd
david;
...
}

1
gas 0

yummy
boom!
Class Composition &
Construction/Destruction
What does it print?

class Stomach
{
public:
Stomach(void) { cout<<“Mmm foodn”; }
~Stomach() { cout << “Poof!n”; }
};
class Nerd
{
public:
Nerd(void) { cout<<“I like integralsn”; }
~Nerd() { cout << “Oh derivatives!n”; }
private:
Stomach belly;
};

int main(void)
{
Nerd
herbert;
...
}

Mmm food
I like integrals
Oh derivatives
Poof!
Class Composition
Let’s examine a slightly different Stomach class.
Here’s the Stomach’s specification:
• When a Stomach is constructed, you must specify how
many farts it starts with. It prints out the starting
number of farts
• You can add farts to a Stomach with an eat method
• When a Stomach is destructed, it farts N times
Class Composition
class Stomach
{
public:
Stomach(int startFarts)
{
farts = startFarts;
cout << “Start farts: “ << farts;
}
void eat()
{
farts ++;
}
~Stomach()
{ while (farts-- > 0)
cout << “pffft!”; }
private:
int farts;
};

int main(void)
{
Stomach a(5); // 5 farts
Stomach b; // ???

}
 

a.eat(); // 6 farts
...

Now, what happens if we
want to use our new
Stomach class in a Nerd?
Class Composition
class Stomach
{
public:
Stomach(int startFarts)
{
farts = startFarts;
cout << “Start farts: “ << farts;
}
void eat()
{
farts ++;
}
~Stomach()
{ while (farts-- > 0)
cout << “pffft!”; }
private:
int farts;
};

class Nerd
{
public:
Nerd(void)
{
thought = "CS";
}
~Nerd()
{ cout << “Argh “ << thought; }
private:
Stomach belly;
string thought;
};

Will this work?
NO!
But doesn’t
Class Composition
specify the

required starting Nerd
class
class Stomach
# of farts!!! {
{
public:
public:
Nerd(void)
Stomach(int startFarts)
{
{
thought = "CS";
Your Nerd has a
farts = startFarts;
}
cout << “Start farts: “ << farts;
Stomach
}
~Nerd()
variable…
{ cout << “Argh “ << thought; }
void eat()
{
private:
farts ++;
Stomach belly;
}
string thought;
};
~Stomach()
{ while (farts-- > 0)
This won’t work because you
cout << “pffft!”; }
private:
int farts;
};

must pass in a # of farts any
time you construct a Stomach.
But our Nerd doesn’t do that!
Class Composition
class Stomach
{
public:
Stomach(int startFarts)
{
farts = startFarts;
cout << “Start farts: “ << farts;
}
void eat()
{
farts ++;
}
~Stomach()
{ while (farts-- > 0)
cout << “pffft!”; }
private:
int farts;
};

class Nerd
{
public:
Nerd(void)
{
thought = "CS";
}
~Nerd()
{ cout << “Argh “ << thought; }
private:
Stomach belly;(10); // Good?
string thought;
};

Q: How can we fix our Nerd?
A: By properly specifying the
# of farts when we construct
a Stomach??
Class Composition
This means:

“Before you construct the Nerd…

class Nerd
class Stomach
first construct its Stomach by
{
passing in a value of 10.” {
public:
public:
Nerd(void) : belly(10)
Stomach(int startFarts)
{
{
thought = "CS";
farts = startFarts;
}
cout << “Start farts: “ << farts;
}
~Nerd()
{ cout << “Argh “ << thought; }
void eat()
{
private:
farts ++;
Stomach belly;
}
string thought;
};
~Stomach()
{ while (farts-- > 0)
A: You MUST explicitly
cout << “pffft!”; }
private:
int farts;
};

construct a contained class
variable using an initializer list
in your constructor.
Class Composition

belly
class Nerd
farts
10
{
"CS"
thought
public:
Nerd(void) : belly(10)
{
thought = "CS";
}

class Stomach
{
10
public:
Stomach(int startFarts)
{
farts = startFarts;
cout << “Start farts: “ << farts;
}

~Nerd()
{ cout << “Argh “ << thought; }

void eat()
{
farts ++;
}
~Stomach()
{ while (farts-- > 0)
cout << “pffft!”; }
private:
int farts;
};

carey

private:
Stomach belly;
string thought;
};
int main(void)
{
Nerd carey;
}

...

Start farts: 10
Class Composition
In our current Nerd, the Stomach always starts out
with 10 farts of gas…
Challenge: Modify the Nerd class so you can pass in the
number of farts of gas that the Nerd starts with.
class Nerd
{
public:
Nerd(void) : belly(10)
{
thought = “CS”;
}
~Nerd()
{ cout << “Argh “<< thought; }
private:
Stomach belly;
string thought;
};

class Nerd
{
public:
Nerd( intvoid ) : belly( farts )
10
farts
{
thought = “CS”;
}
~Nerd()
{ cout << “Argh “<< thought; }
private:
Stomach belly;
string thought;
};
Class Composition
class Stomach
{
public:
3
Stomach(int startFarts)
{
farts = startFarts;
cout << “Start farts: “ << farts;
}
void eat()
{
farts ++;
}
~Stomach()
{ while (farts-- > 0)
cout << “pffft!”; }
private:
int farts;
};

Carey

belly

farts

class Nerd
thought
{
public:
3
3
Nerd(int farts) : belly(farts)
{
thought = "CS";
}

3
“CS”

~Nerd()
{ cout << “Argh “ << thought; }
private:
Stomach belly;
string thought;
};
int main(void)
{
Nerd Carey(3);
}

...

Start farts: 3
Class Composition

Challenge:
Our current Nerd only has one Stomach.

Create a NerdyCow class that has two Stomachs and a thought.
When you construct the NerdyCow, you should be able to specify
how many farts start out in each stomach and its thought.
class Nerd
{
public:
Nerd(int farts) : belly(farts)
{
thought = "CS";
}
~Nerd()
{ cout << “Argh “ << thought; }
private:
Stomach belly;
string thought;
};

class NerdyCow
{
public:

NerdyCow(int f1, int f2, string &idea)
: belly1(f1), belly2(f2)

{
}

thought = idea;

~NerdyCow() { cout << “Moooo!”; }
private:
Stomach belly1;
Stomach belly2;
string thought;
};
earl

Class Composition
class Stomach
{
public:
7
8
Stomach(int startFarts)
{
farts = startFarts;
cout << “Start farts: “ << farts;
}
void eat()
{
farts ++;
}
~Stomach()
{ while (farts-- > 0)
cout << “pffft!”; }
private:
int farts;
};

belly1

farts

class NerdyCow
{
public:
7

7

belly2

farts

8

8

thought

“milk”
“milk”

NerdyCow(int f1, int f2, string &idea)
: belly1(f1), belly2(f2)

{
}

thought = idea;

~NerdyCow() { cout << “Moooo!”; }
private:
Stomach belly1;
Stomach belly2;
string thought;
};

Start farts: 7
Start farts: 8

int main(void)
{
NerdyCow earl(7,8, “milk”);
}

...
A Few Final Topics
Let’s talk about three final topics that you’ll need in
order to solve your Project #1…
Topic #1: Include Etiquette
A. Never include a CPP file in another .CPP or .H file.
file1.cpp
void someFunc(void)
{
cout << “I’m cool!”
}

file2.cpp
#include “file1.cpp”
void otherFunc(void)
{
cout << “So am I!”
someFunc();
}

You’ll get linker
errors.
Only include .H files
within a .CPP file.
Topic #1: Include Etiquette
B. Never put a “using namespace” command in a header file.
someHeader.h
#include <iostream>
using namespace std;

hello.cpp
#include “someHeader.h”
// BUT I DON’T WANT THAT
// NAMESPACE! YOU BASTARD!
int main()
{
cout << “Hello world!”;
}

So this is bad…
This is called
“Namespace Pollution”
Why? The .H file is
forcing CPP files that
include it to use its
namespace.
And that’s just selfish.
Instead, just move the “using”
commands into your C++ files.
alcohol.h
class Alcohol
{
...
};

student.h

#include “redbull.h”
"alcohol.h"
class Student
{
...
private:
RedBull bottles[5];
Alcohol
};

main.cpp

#include “student.h”
#include "alcohol.h"
int main()
{

Student larry;
Alcohol vodka;

Topic #1: Include
And in fact, this works right
Etiquette
now, because student.h does
include alcohol.h.

C. Never assume that a header
file will include some other
header file will you.
Now your main.cpp fileif the author
But what happens forcompile

correctly regardlessdecides to change
of student.h of what’s contained
in the otherimplementation?
What can you do?
it’s header files it uses!

Always DIRECTLY include the
header files you need RIGHT
where you need them.
main.cpp defines an Alcohol variable
but Utoh! Now main.cpp no longer
it doesn’t #include"alcohol.h".
In this case, main.cpp has a
compiles! 
Why? Student variable student.h will
It assumes that and an Alcohol
variable. So doesn’t it.
just Because itit shouldinclude
Why?include alcohol.h for include
both of their header files.
alcohol.h but it defines an Alcohol
variable!

cout << larry << “ is drinking “ << vodka;
}
Topic #2: Preprocessor Directives
C++ has several special commands which you sometimes
need in your programs.
Command 1: #define
You can use the #define command to define new constants:

file.cpp
#define PI 3.14159
#define FOOBAR
void someFunc(void)
{
cout << PI;
}

You can also use #define to define a new constant without
specifying a value! Why you ask? We’ll see!
Preprocessor Directives
Command 2: #ifdef and #endif
Since a constant has
You can use the #ifdef command to check if FOOBAR was
was defined I’llI’ll
NOT defined
been defined already…

The compiler
only compiles the code
between the
#ifdef and the #endif
if the constant was defined.

compile the code
ignore the code
until #endif.
until #endif.

file.cpp

#define FOOBAR
#ifdef FOOBAR
/*
void someFunc(void)
{
cout << PI;
}
#endif
*/
Preprocessor Directives
Command 2: #ifndef and #endif
Since FOOBAR was
Since FOOBAR
You can use the #ifndef command to check if a constant has
NOT defined
was defined I’llI’ll
NOT been defined already…
compile the code
ignore the code
until #endif.
until #endif.

The compiler
file.cpp
only compiles the code
#define FOOBAR
between the
#ifndef and the #endif
#ifndef FOOBAR
/*
if the constant was NOT defined. void someFunc(void)
{

cout << PI;
}
#endif
*/
Separate Compilation
calc.h

class Calculator
{
public:
void compute();
...
};

calc.cpp
#include “calc.h”

Can anyone see
what the
problem is?

student.h

#include “calc.h”
class Student
{
public:
void study()
...
private:
Calculator myCalc;
};

main.cpp

#include “student.h”
int Calculator::compute()
student.cpp
#include “calc.h”
{
#include “student.h”
main.cpp
...
int main()
#include “student.h”
}
int Student::study()
{
{
Student
int main()grace;
cout << myCalc.compute();{ Calculator hp;
}
...
Student grace;

When–using class composition,(and
Now something interesting it
Then you can use them like this in
bad) happens if I each class in a in
helps to define use both classes
your main program…
separate pair of .cpp/.h files.
my main program. Let’s see!

grace.study();
...
hp.compute();
grace.study();
}
Separate Compilation
calc.h

student.h

So what’s
problem?
class Calculator the#include “calc.h”
{
class Student
public:
Well, since main.cpp and student.h both
{
void compute();
included calc.h, we ended up with two
public:
...
That’s bad!
}; definitions of Calc! void study()
...
private:
calc.cpp
This can result in a compiler error!
Calculator myCalc;
#include “calc.h”
};

main.cpp
#include “student.h”
#include “calc.h”
int main()
{
Student grace;
Calculator hp;
...
grace.study();
hp.compute();
}

main.cpp

class Student we fix it, you ask?
#include “student.h”
int Calc::compute()
So how do
student.cpp
{
#include “calc.h”
#include “student.h”
main.cpp
public:
...
Here’s how…
int main()
#include “student.h”
} void study()
int Student::study()
...
{
{
private:
Student
int main()grace;
Calculator myCalc; cout << myCalc.compute();{ Calculator hp;
}
};
...
Student grace;
grace.study();
...
Your main program first includes calc.h… again!
Then student.h then
…and finally, main.cpp
hp.compute();
grace.study();
includes student.h…
includes calc.h!
}
main.cpp

Separate Compilation
calc.h when the
Now,

#ifndef CALC_H
compiler compiles

#ifndef STUDENT_H
#define STUDENT_H

#ifndef CALC_H
#define CALC_H
class Calculator
{
public:
void compute();
};
#endif // for CALC_H

Once the compilation
is done, the compiler
Compiler: Since no
Compiler: all user
discards The of the
one’s defined
STUDENT_H, no
Compiler: SinceI’ll
#has defined
commands...

this code, it will
ignore the redefined
definitions!
Compiler: The user
STUDENT_H. I’ll
keep compiling.
one’s defined
class Calculator
has defined
remember keep
CALC_H, I’llthat!
class Student student.h
{
Compiler:
CALC_H. I’ll
{
And you compiling. that only
can see
public:
public:
#ifndef STUDENT_H remember that!
STUDENT_H has
void study()
one copy of each definition
void compute(); private:
Compiler: Ok, I just
been defined!
#define STUDENT_H
Calculator myCalc;
...
finished with the
is now included!
};
};
CALC_H has been
#include “calc.h”
#ifndef CALC_H
#endif // for STUDENT_H
defined!
block of code…
#endif // for CALC_H
#ifndef CALC_H
class Student
#define CALC_H
Compiler: Ok, I just
class Calculator
{
finished Ok, I this
{
MakeCompiler:with the any
sure you do just
public:
public:
finished with the
void compute(); void study() you Compiler: The
time #ifndef CALC_H files
define header
block of constant
};
#ifndef STUDENT_H
An Add “include#endif a for CALC_H
So what would our //
include guard is
CALC_H code…
...
from now on…
block of defined.
was alreadycode…
int
special check that
fully-compiled main() private:
guards” to each
{
I’ll ignore the code
Student
prevents duplicate grace; Calculator myCalc; your #endif!safer!
program look like
It makes the code
header file. Calculator hp;
until
};
...
header inclusions.
now?
#endif // for STUDENT_H
#define CALC_H

grace.study();
hp.compute();
alcohol.h
class Alcohol
{

public:
void drink() { cout << “glug!”; }
};

student.h
#include “alcohol.h”
class Student
{

public:
void beIrresponsible();
...
private:
Alcohol *myBottle;
};

Last Topic: Knowing
WHEN to Include .H Files

You might think that any
time you refer to a class,
you should include it’s .h
file
So I need to include first… Right?
alcohol.h, right?

Well, not so fast!

I use the Alcohol class
(which is defined in
alcohol.h)
to define a member variable
A.h
class FirstClass
{

public:
void someFunc() { ... }
};

B.h
#include “A.h”
class SecondClass
{

public:
void otherFunc()
{
FirstClass y;
FirstClass b[10];
y.someFunc();
return(y);
}
private:
FirstClass x;
FirstClass a[10];
};

Last Topic: Knowing
WHEN to Include .H Files
Here are the rules…

You must include the header
file (containing the full
Why? Because C++ needs toof a class)
definition
know the class’s details in order
to define actual variables Any time…
with it

or to let you call methods from
1. You define a regular variable
it!
of that class’s type, OR
2. You use the variable in any
way (call a method on it,
return it, etc).

On the other hand…
A.h
class FirstClass
{

Last Topic: Knowing
This line tells C++ that your
WHEN to Include .H Files

class exists, but doesn’t actually
public:
void someFunc() { ... the gory details.
define all }

If you do NONE of the
Since none of this code actually but you…
previous items,

};

B.h
class FirstClass;
class SecondClass
{

uses the “guts” of the class (as
// enough!
1. Use the class
the code did on the previous to define a
parameter to
slide), this is all C++ needs to a function, OR
know!Use the class as the
2.

public:
void goober(FirstClass p1);
FirstClass hoober(int a);
void joober(FirstClass &p1);
void koober(FirstClass *p1);
void loober()
{
FirstClass *ptr;
}
private:
FirstClass *ptr1, *z[10];
};

return type for a func, OR

3. Use the class to define a
pointer or reference variable
Then you DON’T need
to include the class’s .H file.
(You may do so, but you don’t need to)

Instead, all you need to do is give
C++ a hint that your class
exists (and is defined elsewhere).
Here’s how you do that:
A.h
class FirstClass
{

… //
public:thousands of lines
…voidthousands of{lines}
// someFunc()
...
};

B.h
#include “A.h” // really slow!
class SecondClass
{

public:

private:
};

Last Topic: Knowing
WHEN to Include .H Files
Wow – so confusing!
Why not just always use #include
to avoid the confusion?
There are two reasons:
1. If a .h file is large (thousands
of lines), #including it when
you don’t strictly need to
slows down your compilation!
2. If two classes refer to each
other, and both classes try to
#include the other’s .H file,
you’ll get a compile error.
Students and Classrooms
Every student knows what class he/she is in…
Every class has a roster of its students…

CS 32
Kerry

Cyril

Kerry
Cyril

Math 31b
Lydia

Hal

Lydia
Hal

These type of cyclical relationships cause #include problems!
Last Topic: Self-referential Classes
And here we have the Student refersto thethat each Student
Since our Student classclass. Note Student class,
HereSince ouraClassRoomclass refers holds aclassroomclass
we have ClassRoomclass the problem? bunch of Students…
Do you see that to the
knows whichincludes ClassRoom.h… in…
it classroom he or she
it includes Student.h is

Student.h

ClassRoom.h

#include “ClassRoom.h”

#include “Student.h”

class Student
{
public:
...

class ClassRoom
{
public:
...

private:
ClassRoom *m_myRoom;
};

private:
Student m_studs[100];
};

Student.cpp

ClassRoom.cpp

#include “Student.h”

#include “ClassRoom.h”

void Student::printMyClassRoom()
{
cout <<“I’m in Boelter #” <<
m_myRoom->getRmNum();
}

void ClassRoom::printRoster()
{
for (int i=0;i<100;i++)
cout << m_studs[i].getName();
}
Last Topic: Self-referential Classes
main.cpp
#include “Student.h”

Student.h
#include “ClassRoom.h”
class Student
{
public:
...
private:

The compiler will keep
ClassRoom
};
going forever!!!!!

*m_myRoom;

ClassRoom.h
#include “Student.h”

int main()
{
Student david;
…
}

class ClassRoom
{
public:
...
private:
Student m_studs[100];
};
So how do we solve this cyclical nightmare?
Step #1:
Look at the two class definitions in your .h files. At least one of
them should NOT need the full #include.
Question:
This our JUST defines a pointer
Which ofclass two classes doesn’t need the full #include? Why?
to a ClassRoom. It does NOT hold
a full ClassRoom variable and
therefore doesn’t require the full
class definition here!!!

Student.h

This class defines actual
Student variables… It
therefore requires the full
class definition to work!

ClassRoom.h

#include “ClassRoom.h”

#include “Student.h”

class Student
{
public:
...

class ClassRoom
{
public:
...

private:
ClassRoom *m_myRoom;
};

private:
Student m_studs[100];
};
So how do we solve this cyclical nightmare?
Step #2:
Take the class that does NOT require the full #include
(forget the other one) and update its header file:
Replace the #include “XXXX.h” statement
with the following: class YYY;
Where YYY is the other class name (e.g., ClassRoom).

Student.h

ThisThe Compiler says:
line tells
ClassRoom.h the compiler:

The Programmer says:
“Alright smartypants, I’ll trust you.
#includeCompiler replies:
The “Student.h”
“I think I’ll have a little fun! Let’s“Hey Compiler, there’s
“Wannt playclass called
class Student what the compiler says ifclass ClassRoom me about
But if won’t tell
another nasty? Ok.
see
{I are 9000 SYNTAX ERRORS
{
Here
define a full variable!”ClassRoom’s functions and variables
‘ClassRoom’ but we’re not
public:
public:
for
deal with!”
... can’t
goingyou to define any actual
…then you to tell you exactly
...
whatvariables like just yet.”
it looks with it

X

#include “ClassRoom.h”
class ClassRoom;

private:
ClassRoom *m_myRoom;, haha;
};

private:
Student m_studs[100];
or }; any member functions on it.”
call
So how doAll you need is this
we solve this cyclical nightmare?
class declaration;
line to give the compiler
a heads-up.

Step #3:
Almost done. Now update the
CPP file for this class by
#including the other header
file normally.

Since this .H file JUST has a
pointer to a ClassRoom (but no
This line tells the compiler:
code in this file that uses or
defines #include
So you must a full ClassRoom variable)…
“Hey Compiler, since my CPP
its header file here!

file is going to actually
Student.h
use class’s functionality, I’ll
#include “ClassRoom.h”
You’re calling a member tell you all the details
class ClassRoom;
now The Compiler says:
function of ClassRoom about the class.”
Student.cpp
class Student
here…
#include “Student.h”
{
#include
public: “ClassRoom.h”
void Student::printMyClassRoom()
...
{
cout <<“I’m in Boelter #” <<
private:
m_myRoom->getRmNum();
ClassRoom *m_myRoom;
}
};

Ah, ok, now I can see the full
definition of what a ClassRoom
Thevariable reallyhappy as
compiler is is…

long as you #include the

Feel free to call its getRmNum()
classmethod if you like! you
definition before

actually use the class in
your functions…
So how do we solve this cyclical nightmare?
The Compiler says:

Step #4:
Finally, make sure that your
Hey! Wait a second, you’re
Student.h
calling the getRmNum( )
class doesn’t have any other
#include “ClassRoom.h”
class ClassRoom;
function but you haven’t defined
member functions that violate
class Student
the full class. No WAY!
our #include vs class rules…
{
public:
void beObnoxious() {
void beObnoxious();
…

Fix it or DIE!

cout << m_myRoom->getRmNum() << “ sucks!”; }

private:
ClassRoom *m_myRoom;
};

If you have defined one or
more functions DIRECTLY in
Alright. That’s better.
your class definition AND they
Student.cpp
use your other class in a
#include “Student.h”
Don’t let it happen again.
significant way, then you must
#include “ClassRoom.h”
void Student::printMyClassRoom()
MOVE them to the CPP file.
The Compiler says:

{void Student::beObnoxious() {
cout << m_myRoom->getRmNum() << “ sucks!”; }
cout <<“I’m in Boelter #” <<
m_myRoom->getRmNum();
}
So how do we solve this cyclical nightmare?
Now let’s look at both of our classes… Notice, we no longer
have a cyclical reference! Woohoo!

Student.h

#include “ClassRoom.h”
class ClassRoom;

ClassRoom.h
#include “Student.h”

class Student
{
public:
...

class ClassRoom
{
public:
...

private:
ClassRoom *m_myRoom;
};

private:
Student m_studs[100];
};

Student.cpp
#include “Student.h”
#include “ClassRoom.h”
void Student::printMyClassRoom()
{
cout <<“I’m in Boelter #” <<
m_myRoom->getRmNum();
}

ClassRoom.cpp
#include “ClassRoom.h”
void ClassRoom::printRoster()
{
for (int i=0;i<100;i++)
cout << m_studs[i].getName();
}
Class Challenge
RULES
• The class will split into left and
right teams
• One student from each team will
come up to the board
• Each student can either
– write one new line of code to solve
the problem OR
– fix a single error in the code their
teammates have already written

• Then the next two people come up,
etc.
• The team that completes their
program first wins!

Team #1
VOID
float FUNC()
int

Team #2
int func(int * v)
int
{ while(v > 0)
Challenge #1
Write a class called quadratic which represents a
second-order quadratic equation, e.g.: 4x2+3x+5
When you construct a quadratic class, you pass in the
three coefficients (e.g., 4, 3, and 5) for the equation.
The class also has an evaluate method which allows you
pass in a value for x. The function will return the value
of f(x).
The class has a destructor which prints out “goodbye”
Challenge #2
Write a class called MathNerd which represents a
math nerd. Every MathNerd has his own special
quadratic equation!
When you construct a MathNerd, he always wants you
to specify the first two coefficients (for the x2 and x)
for his equation. The MathNerd always selects a value
of PI for his final coefficient.
The MathNerd had a getMyValue function which accepts
a value for x and should return f(x) for the nerd’s QE.

More Related Content

What's hot

Toonz code leaves much to be desired
Toonz code leaves much to be desiredToonz code leaves much to be desired
Toonz code leaves much to be desiredPVS-Studio
 
openFrameworks 007 - GL
openFrameworks 007 - GL openFrameworks 007 - GL
openFrameworks 007 - GL roxlu
 
Node.js API pitfalls
Node.js API pitfallsNode.js API pitfalls
Node.js API pitfallsTorontoNodeJS
 
JS Fest 2019 Node.js Antipatterns
JS Fest 2019 Node.js AntipatternsJS Fest 2019 Node.js Antipatterns
JS Fest 2019 Node.js AntipatternsTimur Shemsedinov
 
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsTypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsAlfonso Peletier
 

What's hot (8)

Toonz code leaves much to be desired
Toonz code leaves much to be desiredToonz code leaves much to be desired
Toonz code leaves much to be desired
 
openFrameworks 007 - GL
openFrameworks 007 - GL openFrameworks 007 - GL
openFrameworks 007 - GL
 
Es6 overview
Es6 overviewEs6 overview
Es6 overview
 
Java Threads
Java ThreadsJava Threads
Java Threads
 
Node.js API pitfalls
Node.js API pitfallsNode.js API pitfalls
Node.js API pitfalls
 
147301 nol
147301 nol147301 nol
147301 nol
 
JS Fest 2019 Node.js Antipatterns
JS Fest 2019 Node.js AntipatternsJS Fest 2019 Node.js Antipatterns
JS Fest 2019 Node.js Antipatterns
 
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsTypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
 

Viewers also liked

Viewers also liked (9)

Lurraldea Libro I
Lurraldea Libro ILurraldea Libro I
Lurraldea Libro I
 
Catálogo museografico
Catálogo museograficoCatálogo museografico
Catálogo museografico
 
Toros
TorosToros
Toros
 
Alegoría Del Amor
Alegoría Del  AmorAlegoría Del  Amor
Alegoría Del Amor
 
Remedios varo
Remedios varoRemedios varo
Remedios varo
 
SURREALISMO: REMEDIOS VARO Y MARC CHAGALL
SURREALISMO: REMEDIOS VARO Y MARC CHAGALLSURREALISMO: REMEDIOS VARO Y MARC CHAGALL
SURREALISMO: REMEDIOS VARO Y MARC CHAGALL
 
4.3.2
4.3.24.3.2
4.3.2
 
Remedios Varo
Remedios VaroRemedios Varo
Remedios Varo
 
Varo Remedios
Varo RemediosVaro Remedios
Varo Remedios
 

Similar to Lecture 2 constructors:composition

Constructors & Destructors [Compatibility Mode].pdf
Constructors & Destructors [Compatibility Mode].pdfConstructors & Destructors [Compatibility Mode].pdf
Constructors & Destructors [Compatibility Mode].pdfLadallaRajKumar
 
Constructors and destructors in C++
Constructors and destructors in  C++Constructors and destructors in  C++
Constructors and destructors in C++RAJ KUMAR
 
Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016PVS-Studio
 
Constructor and Destructor
Constructor and DestructorConstructor and Destructor
Constructor and DestructorKamal Acharya
 
Object Oriented Programming - Constructors & Destructors
Object Oriented Programming - Constructors & DestructorsObject Oriented Programming - Constructors & Destructors
Object Oriented Programming - Constructors & DestructorsDudy Ali
 
Csphtp1 06
Csphtp1 06Csphtp1 06
Csphtp1 06HUST
 
Dynamic memory allocation in c++
Dynamic memory allocation in c++Dynamic memory allocation in c++
Dynamic memory allocation in c++Tech_MX
 
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptxCONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptxDeepasCSE
 
constructor & destructor in cpp
constructor & destructor in cppconstructor & destructor in cpp
constructor & destructor in cppgourav kottawar
 
constructor & destructor in cpp
constructor & destructor in cppconstructor & destructor in cpp
constructor & destructor in cppgourav kottawar
 
Constructors and Destructors
Constructors and DestructorsConstructors and Destructors
Constructors and DestructorsKeyur Vadodariya
 
friends functionToshu
friends functionToshufriends functionToshu
friends functionToshuSidd Singh
 
exercises_for_live_coding_Java_advanced-2.pdf
exercises_for_live_coding_Java_advanced-2.pdfexercises_for_live_coding_Java_advanced-2.pdf
exercises_for_live_coding_Java_advanced-2.pdfenodani2008
 
Constructors in C++.pptx
Constructors in C++.pptxConstructors in C++.pptx
Constructors in C++.pptxRassjb
 
PVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around DisneyPVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around DisneyPVS-Studio
 
Wade not in unknown waters. Part one.
Wade not in unknown waters. Part one.Wade not in unknown waters. Part one.
Wade not in unknown waters. Part one.PVS-Studio
 

Similar to Lecture 2 constructors:composition (20)

Functional C++
Functional C++Functional C++
Functional C++
 
Constructors & Destructors [Compatibility Mode].pdf
Constructors & Destructors [Compatibility Mode].pdfConstructors & Destructors [Compatibility Mode].pdf
Constructors & Destructors [Compatibility Mode].pdf
 
Constructors and destructors in C++
Constructors and destructors in  C++Constructors and destructors in  C++
Constructors and destructors in C++
 
Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016
 
Constructor and Destructor
Constructor and DestructorConstructor and Destructor
Constructor and Destructor
 
Object Oriented Programming - Constructors & Destructors
Object Oriented Programming - Constructors & DestructorsObject Oriented Programming - Constructors & Destructors
Object Oriented Programming - Constructors & Destructors
 
Csphtp1 06
Csphtp1 06Csphtp1 06
Csphtp1 06
 
Dynamic memory allocation in c++
Dynamic memory allocation in c++Dynamic memory allocation in c++
Dynamic memory allocation in c++
 
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptxCONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
CONSTRUCTORS, DESTRUCTORS AND OPERATOR OVERLOADING.pptx
 
constructor & destructor in cpp
constructor & destructor in cppconstructor & destructor in cpp
constructor & destructor in cpp
 
constructor & destructor in cpp
constructor & destructor in cppconstructor & destructor in cpp
constructor & destructor in cpp
 
Constructors and Destructors
Constructors and DestructorsConstructors and Destructors
Constructors and Destructors
 
friends functionToshu
friends functionToshufriends functionToshu
friends functionToshu
 
Tut Constructor
Tut ConstructorTut Constructor
Tut Constructor
 
exercises_for_live_coding_Java_advanced-2.pdf
exercises_for_live_coding_Java_advanced-2.pdfexercises_for_live_coding_Java_advanced-2.pdf
exercises_for_live_coding_Java_advanced-2.pdf
 
Constructors in C++.pptx
Constructors in C++.pptxConstructors in C++.pptx
Constructors in C++.pptx
 
PVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around DisneyPVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around Disney
 
Class ‘increment’
Class ‘increment’Class ‘increment’
Class ‘increment’
 
Wade not in unknown waters. Part one.
Wade not in unknown waters. Part one.Wade not in unknown waters. Part one.
Wade not in unknown waters. Part one.
 
Intro
IntroIntro
Intro
 

Recently uploaded

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfjimielynbastida
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsPrecisely
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentationphoebematthew05
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 

Recently uploaded (20)

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdf
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Unlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power SystemsUnlocking the Potential of the Cloud for IBM Power Systems
Unlocking the Potential of the Cloud for IBM Power Systems
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
costume and set research powerpoint presentation
costume and set research powerpoint presentationcostume and set research powerpoint presentation
costume and set research powerpoint presentation
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 

Lecture 2 constructors:composition

  • 1. Wednesday, Jan 11 Collect Academic Integrity Forms Constructors Destructors Class Composition Composition with Initializer Lists A few final topics required for Project #1 • Learning how to use the VC debugger (time permitting) • • • • • • th
  • 2. Constructors: Class Initialization Every class should have an initialization function that can be used to reset new variables before they’re used. class CSNerd { public: void Init(int PCs, bool usesMac) { 2 false m_numPCs = PCs; // # of PCs owned void Init(int PCs, bool usesMac) Ack! How can david { m_macUser = usesMac; m_numPCs = PCs; m_macUser = usesMac; } someone have -32 } computers? 10*2 = 20 int int getNerdScore(void) { if(m_macUser == true) return(0); return(10 * m_numPCs); } m_numPCs -32 m_macUser getNerdScore(void) { false if(m_macUser == true) return(0); //not nerdy; “artistic” return(10 * m_numPCs); } main() { private: CSNerd david; int m_numPCs; Right! Our programmer might But all simple variables Well, remember, there’s one problem david.Init(2,false); // geeky So if you forget to call the Init bool m_macUser; forget with such anInit to call the Init (e.g., ints, bools, CSNerd’s member cout << david.getNerdScore(); function, your etc.) in C++ start out }; function before values. Not variables will have randomusing is it? } with random function… What the values unless they’re what you’d want. variable…Here’s ahappen? explicitly What’ll hint! initialized!
  • 3. class CSNerd { public: void Init(int PCs, bool usesMac) { m_numPCs = PCs; m_macUser = usesMac; } int getNerdScore(void) { if(m_macUser == true) return(0); return(10 * m_numPCs); } private: int m_numPCs; bool m_macUser; }; Constructors Wouldn’t it be great if C+ + would guarantee that every time we create a new class variable, it’ll be auto-initialized? Well, as it turns out, that’s exactly what the C++ constructor does! main() { CSNerd david; cout << david.getNerdScore(); }
  • 4. class CSNerd Since the constructor is { called automatically any time public: you void Init(int define bool usesMac) CSNerd (int PCs, a new variable… { m_numPCsthere’s no chance of a new = PCs; variable being m_macUser = usesMac; uninitialized accidentally. } int getNerdScore(void) { if(m_macUser == true) return(0); return(10 * m_numPCs); } private: int m_numPCs; bool m_macUser; }; Constructors main() { (3,true); CSNerd chen;3 true chen.Init(3,true); cout << chen.getNerdScore(); } true 3 Instead constructor is The of being called CSNerd(int chen called PCs, bool usesMac) { Init, the=automatically constructor m_numPCs PCs; m_macUser = usesMac; functiontime the same } every has you create int getNerdScore(void) name as the class! { a new instance of if(m_macUser == (Confusing, true) huh?) return(0); your class. return(10 * m_numPCs); } m_numPCs m_macUser A constructor is a special member function that automatically initializes every new variable you create of that class.
  • 5. And remember to also include just the function header, followed by a class CSNerd semicolon, in the class { declaration itself. Constructors class CSNerd public: { CSNerd(int PCs, bool usesMac); public: { CSNerd(int PCs, bool usesMac) m_numPCs Boy, isn’t that syntax ugly? = PCs; { m_macUser = usesMac; m_numPCs = PCs; Just remember, to define } m_macUser = usesMac; ... a constructor outside the } return(true); //illegal! class declaration: } private: ... private: int m_numPCs; bool m_macUser; }; int m_numPCs;use the class name, bool m_macUser; by ::, followed by followed }; the class name. CSNerd:: You can define the LikeconstructorA theno return is a special constructor To summarize…inhas class constructor type! It’s not The all other member functions, the declaration (see not void, int, have new constructor’sit’s above)…be defined inside function in your logic can initializes athe The constructor function allowed! Notice class thatMUST or bool. Or, outside the class variable whennot first created. SAME NAME AS class to return a value. or outside the alloweddeclaration. declaration, like this… And thus it’s its THE CLASS!
  • 6. Constructors If a constructor requires parameters: class CSNerd { public: CSNerd(int PCs, bool usesMac ) { m_numPCs = PCs; 0; m_macUser = usesMac; false; } int getNerdScore(void) { if(m_macUser == true) return(0); return(10 * m_numPCs); } private: int m_numPCs; bool m_macUser; }; You must to provide values for those parameters when you create a new variable: main() { CSNerd ed(1,true); // OK ed(1,true);//invalid! CSNerd alan; // invalid! OK! }
  • 7. Constructors class CSNerd { public: CSNerd(int PCs, bool usesMac = true ) { m_numPCs = PCs; m_macUser = usesMac; } int getNerdScore(void) { if(m_macUser == true) return(0); return(10 * m_numPCs); } private: int m_numPCs; bool m_macUser; }; Just like any C++ function, a constructor can have one or more default parameters… main() { 1 false CSNerd lyn(1,false); 5 CSNerd ned(5); // OK! CSNerd dave; //invalid! cout << lyn.getNerdScore(); }
  • 8. C++: “I’m confused! Should I call this class CSNerd constructor with default parameters…” { public: CSNerd(int PCs, bool usesMac = true) CSNerd() CSNerd(int PCs=1, bool usesMac=true) Your class can have many { different constructors. C++: m_numPCs = PCs; m_numPCs = 1; “…or should I call this (this is called overloading m_macUser = false; = usesMac; constructor with no parameters?” m_macUser constructors) } main() int getNerdScore(void) { { Constructors if(m_macUser == true) return(0); return(10 * m_numPCs); } CSNerd lyn(1,false); CSNerd ned(5); // OK! CSNerd dave; // OK!!! //invalid! cout << lyn.getNerdScore(); } private: int m_numPCs; bool m_macUser; }; One more thing: If you have 2 or more constructors, they cannot have the exact same parameters/types.
  • 9. Constructors If you don’t define any constructors at all… class CSNerd { public: then C++ will provide an implicit, default constructor for you that basically does nothing! int getNerdScore(void) by compiler CSNerd() // generated { if(m_macUser == true) // I do nothing at all. //return(0); I’m not worthy!!!!! } return(10 * m_numPCs); } private: int m_numPCs; bool m_macUser; }; main() { CSNerd carey; // OK } cout << carey.getNerdScore(); //?? In this case, your member variables are never initialized.
  • 10. Constructors & Arrays class CSNerd { public: CSNerd(int PCs, bool usesMac = true) { m_numPCs = PCs; m_macUser = usesMac; } 1 false 1 false 1 false 1 false CSNerd() { m_numPCs = 1; m_macUser = false; } ... private: int m_numPCs; bool m_macUser; When you define an array, the your class, If you want to have an array of }; constructor is run on every your class must have a constuctor that element in the no arguments! requires array! main() { CSNerd lec1[4]; cout << lec1[0].getNerdScore(); }
  • 11. Constructors There are several different ways to initialize your member variables in a constructor. Here’s the easiest way: class CSNerd { public: CSNerd(int PCs, bool usesMac) { m_numPCs = PCs; Class CSNerd m_macUser = usesMac; { } public: ... Or, if you’re really masochistic, you can do a little of both. Here’s a more complex way that does the same thing… This is called an “initializer list” CSNerd(int PCs, bool usesMac) { : m_numPCs (PCs) , m_macUser (usesMac) } ... // I don’t need to do anything! m_macUser = usesMac;
  • 12. Constructor Challenge class CSProf { public: // version #4 #3 #2 #1 39) CSProf(const string &name, int age = 39); { : m_name(name), m_age(age) { m_name = name; // do nothing else m_age = age; } Define a constructor that initializes a CSProf. The user can specify the name of the prof and his/her age. Notice youIf the user omits the don’t put theage, then the prof’s default age is 39. “= 39” here too! ... private: string m_name; int m_age; }; // version #2 #4 CSProf::CSProf(const string &name, int age) { : m_name(name), m_age(age) { m_name = name; // do nothing else m_age = age; } int main(void) { CSProf a(“David”,52); CSProf b(“Carey”); }
  • 13. When Constructors are Called A constructor is called any time you create a new variable for a class. A constructor is called N times when you create an array of size N. A constructor is called when you use new to dynamically allocate a new variable or an array. (we’ll learn new later) The constructor is not called when you just define a pointer variable. main() { CSNerd carey(3,false), bill; // called once for each var CSNerd arr[52]; // constructor’s called 52 times CSNerd *ptr = new CSNerd(1,3); // c’tor called once CSNerd *dyn = new CSNerd[6]; // c’tor called 6 times CSNerd *justAPtr; // c’tor is NOT called
  • 14. Class Challenge Name all the times the CSNerd constructor is called in this example… class CSNerd { public: CSNerd() { m_numPCs = 1; m_macUser = true; } ... private: int m_numPCs; bool m_macUser; }; void foo() { CSNerd *herbert = new CSNerd; } void main(void) { int j; CSNerd *ptrToNerd; CSNerd xavier; for (j=0;j<3;j++) { CSNerd a[5]; foo(); } }
  • 15. Destructors Just as every class has a constructor, every class also has a destructor function (one and only one of these). The job of the destructor is to de-initialize or destruct each variable of a class when the variable goes away. Destructors return nothing and take NO parameters. class SomeClass { public: SomeClass(); // ~SomeClass() ~SomeClass(); // { private: // ... destructor code // }; } private: SomeClass::~SomeClass() ... // { }; // destructor code } constructor destructor! whatever whatever To define a d’tor function, you use the tilde ~ character in front of the class’s name: Or define the destructor function outside your class… and just add a function header inside the class declaration.
  • 16. Ben’s Balance: $990 $1290 $1270 $1280 $1260 $1000 PayPerUseBank.com (we charge by the minute!) Ben we need a Destructor? Why doDover CSRules Here we have a class that allows ib disappears banking. Hmmm… us to do internetwhen $300 CSRules Ben Dover Let’s see but the user main exits,what happens when class InternetBanking Wow – we just logged we use this class without a forgot to call stopBanking, { destructor. public:on and they’re so our PC is still connected voidalready charging startBanking(string nm,string pw) Of course, had we added to (and being charged by) a { fees! m_ic.connect(“payperusebank.com”); destructor… None of this the bank! m_ic.send(nm); // send name m_ic.send(pw); // send password } would have happened… int main(void) void stopBanking(){ m_ic.disconnect(); } { Now, when ourib ib void deposit(float amount) { … } InternetBanking ib; variable goes away, ~InternetBanking() C++ will automatically { string name, pw; m_ic.disconnect(); cin >> name >> pw; call it’s destructor!!! } ib.startBanking(name,pw); private: ib.deposit(300); InternetConnection m_ic; } };
  • 17. When must you have a destructor? Any time a class… Allocates data using the new command Opens a disk file Opens a network connection Your class must have a destructor that… Frees the allocated memory Closes the disk file Disconnects the network connection Don’t forget or you’ll FAIL!
  • 18. Destructors So when is a destructor called anyway? Local function variables are destructed any time a function exits. Local variables defined in a block are destructed when the block finishes. Dynamically allocated variables are destructed when delete is called before the memory is actually freed by the operating system. void Dingleberry(void) { SomeClass c; Oh, and what about arrays? When an array goes away, the destructor is called for every item in the array (just like construction). for (int j=0;j<10;j++) { SomeClass v; // do something } v’s destructor is called each time we hit the end of the block InternetBanking *ib = new InternetBanking(“Carey”,”MyPassword”); // do something delete ib; The d’tor is called for ib by C++ here c’s destructor is called. }
  • 19. Class Challenge #2 Name all the times the CSNerd destructor is called in this example… class CSNerd { public: CSNerd() { m_numPCs = 1; m_macUser = true; } ~CSNerd() { void foo() { CSNerd a, *b; } Question: How could we make our program more efficient? void main(void) where this is (Hint: Look { pointing) int j; CSNerd *ptr, x; ptr = new CSNerd; for (j=0;j<3;j++) { CSNerd a[5]; foo(); } delete ptr; cout <<“Argh! I’m dying. Where’s my iphone?”; } ... private: int m_numPCs; bool m_macUser; }
  • 20. Can you guess? Programming Language Inventor Or Serial Killer See if you can guess who uses a keyboard and who uses a chainsaw!
  • 21. Class Composition Class composition: If a class contains one or more classes as member variables, then you are using class composition: class Valve class GasTank { … }; class Car { ... private: GasTank myTank; }; { … }; Class Composition Class Composition Class Composition class Heart { … }; private: Valve m_valves[4]; class TinMan { ... private: Heart m_myHeart; };
  • 22. class Stomach { public: Stomach() { gas = 0; } ~Stomach() { cout << “boom!”; } void eat() { cout << “yummy”; gas ++; } void fart() { gas--; cout << “pffft!”; } private: }; int gas; class Nerd { public: Nerd() { thought=“Waaa”; belly.eat(); } void meetCuteGirl(string &herName) { } thought = “H.O.T. HOT!”; belly.fart(); ~Nerd() { thought=“Argh”; belly.eat( ); } private: string thought; Stomach belly; }; Composition In this example, our Nerd class holds a Stomach variable (every nerd has a stomach) When using composition, the outer class (Nerd) can use all of the public functions of the contained variable (belly) in: • The outer class’s constructor(s) • The outer class’s functions • The outer class’s destructor Ok, that was easy… But now let’s look into how construction and destruction work with composition…
  • 23. class Stomach { public: Stomach() { gas = 0; } ~Stomach() { cout << “boom!”; } void eat() { cout << “yummy”; gas ++; } void fart() { gas--; cout << “pffft!”; } private: }; int gas; Composition and Construction When we create a Stomach variable, its constructor is called. And when the variable goes away, its destructor is called… s gas int main(void) { Stomach s; ... // use s } boom! 0
  • 24. class Stomach { public: Stomach() { gas = 0; } ~Stomach() { cout << “boom!”; } void eat() { cout << “yummy”; gas ++; } Hint: void fart() { gas--; cout << “pffft!”; } private: }; int gas; class Nerd { When we How can Nerd’screate a Nerd variable, belly constructor use the Nerd’s constructor variable if belly must be called. hasn’t been constructed? But our Nerd contains a Stomach, so its constructor must be called too! public: Nerd() { thought=“Waaa”; belly.eat( ); } void meetCuteGirl(string &herName) { } So which constructor is called first? Nerd’s or Stomach’s? thought = “H.O.T. HOT!”; belly.fart(); ~Nerd() { thought=“Argh”; belly.eat(); } private: string thought; Stomach belly; }; Composition and Construction int main(void) { Nerd david; ... }
  • 25. class Stomach { public: Composition and Since theConstruction Stomach was Stomach() { gas = 0; } ~Stomach() { cout << “boom!”; } C++ constructs the void eat() { cout << “yummy”; gasalready constructed, our ++; } contained class void fart() { gas--; cout << “pffft!”; } class can use it in its first, Nerd private: }; int gas; class Nerd { public: Nerd() { thought=“Waaa”; belly.eat( ); } void meetCuteGirl(string &herName) { } thought = “H.O.T. HOT!”; belly.fart(); ~Nerd() { thought=“Argh”; belly.eat(); } private: string thought; Stomach belly; }; and the outer class second. constructor! So our Stomach is constructed first and then Nerd is constructed after. david thought “Waaa” belly gas int main(void) { Nerd david; ... } 1 0 yummy!
  • 26. class Stomach { public: Stomach() { gas = 0; } ~Stomach() { cout << “boom!”; } void eat() { cout << “yummy”; gas ++; } void fart() { gas--; cout << “pffft!”; } private: }; int gas; class Nerd { public: Nerd() } thought = “H.O.T. HOT!”; belly.fart(); ~Nerd() { thought=“Argh”; belly.eat(); } private: string thought; Stomach belly; }; Now what happens when our Nerd is destructed? Destruction happens in the reverse order. The outside destructor runs first, then the contained destructor runs second. the Stomach has not Since been destructed yet, it { thought=“Waaa”; belly.eat( ); still bedavid by Nerd! can } used thought “Waaa” “Argh” void meetCuteGirl(string &herName) { Composition and Destruction belly int main(void) { Nerd david; ... } 1 gas 0 yummy boom!
  • 27. Class Composition & Construction/Destruction What does it print? class Stomach { public: Stomach(void) { cout<<“Mmm foodn”; } ~Stomach() { cout << “Poof!n”; } }; class Nerd { public: Nerd(void) { cout<<“I like integralsn”; } ~Nerd() { cout << “Oh derivatives!n”; } private: Stomach belly; }; int main(void) { Nerd herbert; ... } Mmm food I like integrals Oh derivatives Poof!
  • 28. Class Composition Let’s examine a slightly different Stomach class. Here’s the Stomach’s specification: • When a Stomach is constructed, you must specify how many farts it starts with. It prints out the starting number of farts • You can add farts to a Stomach with an eat method • When a Stomach is destructed, it farts N times
  • 29. Class Composition class Stomach { public: Stomach(int startFarts) { farts = startFarts; cout << “Start farts: “ << farts; } void eat() { farts ++; } ~Stomach() { while (farts-- > 0) cout << “pffft!”; } private: int farts; }; int main(void) { Stomach a(5); // 5 farts Stomach b; // ??? }   a.eat(); // 6 farts ... Now, what happens if we want to use our new Stomach class in a Nerd?
  • 30. Class Composition class Stomach { public: Stomach(int startFarts) { farts = startFarts; cout << “Start farts: “ << farts; } void eat() { farts ++; } ~Stomach() { while (farts-- > 0) cout << “pffft!”; } private: int farts; }; class Nerd { public: Nerd(void) { thought = "CS"; } ~Nerd() { cout << “Argh “ << thought; } private: Stomach belly; string thought; }; Will this work? NO!
  • 31. But doesn’t Class Composition specify the required starting Nerd class class Stomach # of farts!!! { { public: public: Nerd(void) Stomach(int startFarts) { { thought = "CS"; Your Nerd has a farts = startFarts; } cout << “Start farts: “ << farts; Stomach } ~Nerd() variable… { cout << “Argh “ << thought; } void eat() { private: farts ++; Stomach belly; } string thought; }; ~Stomach() { while (farts-- > 0) This won’t work because you cout << “pffft!”; } private: int farts; }; must pass in a # of farts any time you construct a Stomach. But our Nerd doesn’t do that!
  • 32. Class Composition class Stomach { public: Stomach(int startFarts) { farts = startFarts; cout << “Start farts: “ << farts; } void eat() { farts ++; } ~Stomach() { while (farts-- > 0) cout << “pffft!”; } private: int farts; }; class Nerd { public: Nerd(void) { thought = "CS"; } ~Nerd() { cout << “Argh “ << thought; } private: Stomach belly;(10); // Good? string thought; }; Q: How can we fix our Nerd? A: By properly specifying the # of farts when we construct a Stomach??
  • 33. Class Composition This means: “Before you construct the Nerd… class Nerd class Stomach first construct its Stomach by { passing in a value of 10.” { public: public: Nerd(void) : belly(10) Stomach(int startFarts) { { thought = "CS"; farts = startFarts; } cout << “Start farts: “ << farts; } ~Nerd() { cout << “Argh “ << thought; } void eat() { private: farts ++; Stomach belly; } string thought; }; ~Stomach() { while (farts-- > 0) A: You MUST explicitly cout << “pffft!”; } private: int farts; }; construct a contained class variable using an initializer list in your constructor.
  • 34. Class Composition belly class Nerd farts 10 { "CS" thought public: Nerd(void) : belly(10) { thought = "CS"; } class Stomach { 10 public: Stomach(int startFarts) { farts = startFarts; cout << “Start farts: “ << farts; } ~Nerd() { cout << “Argh “ << thought; } void eat() { farts ++; } ~Stomach() { while (farts-- > 0) cout << “pffft!”; } private: int farts; }; carey private: Stomach belly; string thought; }; int main(void) { Nerd carey; } ... Start farts: 10
  • 35. Class Composition In our current Nerd, the Stomach always starts out with 10 farts of gas… Challenge: Modify the Nerd class so you can pass in the number of farts of gas that the Nerd starts with. class Nerd { public: Nerd(void) : belly(10) { thought = “CS”; } ~Nerd() { cout << “Argh “<< thought; } private: Stomach belly; string thought; }; class Nerd { public: Nerd( intvoid ) : belly( farts ) 10 farts { thought = “CS”; } ~Nerd() { cout << “Argh “<< thought; } private: Stomach belly; string thought; };
  • 36. Class Composition class Stomach { public: 3 Stomach(int startFarts) { farts = startFarts; cout << “Start farts: “ << farts; } void eat() { farts ++; } ~Stomach() { while (farts-- > 0) cout << “pffft!”; } private: int farts; }; Carey belly farts class Nerd thought { public: 3 3 Nerd(int farts) : belly(farts) { thought = "CS"; } 3 “CS” ~Nerd() { cout << “Argh “ << thought; } private: Stomach belly; string thought; }; int main(void) { Nerd Carey(3); } ... Start farts: 3
  • 37. Class Composition Challenge: Our current Nerd only has one Stomach. Create a NerdyCow class that has two Stomachs and a thought. When you construct the NerdyCow, you should be able to specify how many farts start out in each stomach and its thought. class Nerd { public: Nerd(int farts) : belly(farts) { thought = "CS"; } ~Nerd() { cout << “Argh “ << thought; } private: Stomach belly; string thought; }; class NerdyCow { public: NerdyCow(int f1, int f2, string &idea) : belly1(f1), belly2(f2) { } thought = idea; ~NerdyCow() { cout << “Moooo!”; } private: Stomach belly1; Stomach belly2; string thought; };
  • 38. earl Class Composition class Stomach { public: 7 8 Stomach(int startFarts) { farts = startFarts; cout << “Start farts: “ << farts; } void eat() { farts ++; } ~Stomach() { while (farts-- > 0) cout << “pffft!”; } private: int farts; }; belly1 farts class NerdyCow { public: 7 7 belly2 farts 8 8 thought “milk” “milk” NerdyCow(int f1, int f2, string &idea) : belly1(f1), belly2(f2) { } thought = idea; ~NerdyCow() { cout << “Moooo!”; } private: Stomach belly1; Stomach belly2; string thought; }; Start farts: 7 Start farts: 8 int main(void) { NerdyCow earl(7,8, “milk”); } ...
  • 39. A Few Final Topics Let’s talk about three final topics that you’ll need in order to solve your Project #1…
  • 40. Topic #1: Include Etiquette A. Never include a CPP file in another .CPP or .H file. file1.cpp void someFunc(void) { cout << “I’m cool!” } file2.cpp #include “file1.cpp” void otherFunc(void) { cout << “So am I!” someFunc(); } You’ll get linker errors. Only include .H files within a .CPP file.
  • 41. Topic #1: Include Etiquette B. Never put a “using namespace” command in a header file. someHeader.h #include <iostream> using namespace std; hello.cpp #include “someHeader.h” // BUT I DON’T WANT THAT // NAMESPACE! YOU BASTARD! int main() { cout << “Hello world!”; } So this is bad… This is called “Namespace Pollution” Why? The .H file is forcing CPP files that include it to use its namespace. And that’s just selfish. Instead, just move the “using” commands into your C++ files.
  • 42. alcohol.h class Alcohol { ... }; student.h #include “redbull.h” "alcohol.h" class Student { ... private: RedBull bottles[5]; Alcohol }; main.cpp #include “student.h” #include "alcohol.h" int main() { Student larry; Alcohol vodka; Topic #1: Include And in fact, this works right Etiquette now, because student.h does include alcohol.h. C. Never assume that a header file will include some other header file will you. Now your main.cpp fileif the author But what happens forcompile correctly regardlessdecides to change of student.h of what’s contained in the otherimplementation? What can you do? it’s header files it uses! Always DIRECTLY include the header files you need RIGHT where you need them. main.cpp defines an Alcohol variable but Utoh! Now main.cpp no longer it doesn’t #include"alcohol.h". In this case, main.cpp has a compiles!  Why? Student variable student.h will It assumes that and an Alcohol variable. So doesn’t it. just Because itit shouldinclude Why?include alcohol.h for include both of their header files. alcohol.h but it defines an Alcohol variable! cout << larry << “ is drinking “ << vodka; }
  • 43. Topic #2: Preprocessor Directives C++ has several special commands which you sometimes need in your programs. Command 1: #define You can use the #define command to define new constants: file.cpp #define PI 3.14159 #define FOOBAR void someFunc(void) { cout << PI; } You can also use #define to define a new constant without specifying a value! Why you ask? We’ll see!
  • 44. Preprocessor Directives Command 2: #ifdef and #endif Since a constant has You can use the #ifdef command to check if FOOBAR was was defined I’llI’ll NOT defined been defined already… The compiler only compiles the code between the #ifdef and the #endif if the constant was defined. compile the code ignore the code until #endif. until #endif. file.cpp #define FOOBAR #ifdef FOOBAR /* void someFunc(void) { cout << PI; } #endif */
  • 45. Preprocessor Directives Command 2: #ifndef and #endif Since FOOBAR was Since FOOBAR You can use the #ifndef command to check if a constant has NOT defined was defined I’llI’ll NOT been defined already… compile the code ignore the code until #endif. until #endif. The compiler file.cpp only compiles the code #define FOOBAR between the #ifndef and the #endif #ifndef FOOBAR /* if the constant was NOT defined. void someFunc(void) { cout << PI; } #endif */
  • 46. Separate Compilation calc.h class Calculator { public: void compute(); ... }; calc.cpp #include “calc.h” Can anyone see what the problem is? student.h #include “calc.h” class Student { public: void study() ... private: Calculator myCalc; }; main.cpp #include “student.h” int Calculator::compute() student.cpp #include “calc.h” { #include “student.h” main.cpp ... int main() #include “student.h” } int Student::study() { { Student int main()grace; cout << myCalc.compute();{ Calculator hp; } ... Student grace; When–using class composition,(and Now something interesting it Then you can use them like this in bad) happens if I each class in a in helps to define use both classes your main program… separate pair of .cpp/.h files. my main program. Let’s see! grace.study(); ... hp.compute(); grace.study(); }
  • 47. Separate Compilation calc.h student.h So what’s problem? class Calculator the#include “calc.h” { class Student public: Well, since main.cpp and student.h both { void compute(); included calc.h, we ended up with two public: ... That’s bad! }; definitions of Calc! void study() ... private: calc.cpp This can result in a compiler error! Calculator myCalc; #include “calc.h” }; main.cpp #include “student.h” #include “calc.h” int main() { Student grace; Calculator hp; ... grace.study(); hp.compute(); } main.cpp class Student we fix it, you ask? #include “student.h” int Calc::compute() So how do student.cpp { #include “calc.h” #include “student.h” main.cpp public: ... Here’s how… int main() #include “student.h” } void study() int Student::study() ... { { private: Student int main()grace; Calculator myCalc; cout << myCalc.compute();{ Calculator hp; } }; ... Student grace; grace.study(); ... Your main program first includes calc.h… again! Then student.h then …and finally, main.cpp hp.compute(); grace.study(); includes student.h… includes calc.h! }
  • 48. main.cpp Separate Compilation calc.h when the Now, #ifndef CALC_H compiler compiles #ifndef STUDENT_H #define STUDENT_H #ifndef CALC_H #define CALC_H class Calculator { public: void compute(); }; #endif // for CALC_H Once the compilation is done, the compiler Compiler: Since no Compiler: all user discards The of the one’s defined STUDENT_H, no Compiler: SinceI’ll #has defined commands... this code, it will ignore the redefined definitions! Compiler: The user STUDENT_H. I’ll keep compiling. one’s defined class Calculator has defined remember keep CALC_H, I’llthat! class Student student.h { Compiler: CALC_H. I’ll { And you compiling. that only can see public: public: #ifndef STUDENT_H remember that! STUDENT_H has void study() one copy of each definition void compute(); private: Compiler: Ok, I just been defined! #define STUDENT_H Calculator myCalc; ... finished with the is now included! }; }; CALC_H has been #include “calc.h” #ifndef CALC_H #endif // for STUDENT_H defined! block of code… #endif // for CALC_H #ifndef CALC_H class Student #define CALC_H Compiler: Ok, I just class Calculator { finished Ok, I this { MakeCompiler:with the any sure you do just public: public: finished with the void compute(); void study() you Compiler: The time #ifndef CALC_H files define header block of constant }; #ifndef STUDENT_H An Add “include#endif a for CALC_H So what would our // include guard is CALC_H code… ... from now on… block of defined. was alreadycode… int special check that fully-compiled main() private: guards” to each { I’ll ignore the code Student prevents duplicate grace; Calculator myCalc; your #endif!safer! program look like It makes the code header file. Calculator hp; until }; ... header inclusions. now? #endif // for STUDENT_H #define CALC_H grace.study(); hp.compute();
  • 49. alcohol.h class Alcohol { public: void drink() { cout << “glug!”; } }; student.h #include “alcohol.h” class Student { public: void beIrresponsible(); ... private: Alcohol *myBottle; }; Last Topic: Knowing WHEN to Include .H Files You might think that any time you refer to a class, you should include it’s .h file So I need to include first… Right? alcohol.h, right? Well, not so fast! I use the Alcohol class (which is defined in alcohol.h) to define a member variable
  • 50. A.h class FirstClass { public: void someFunc() { ... } }; B.h #include “A.h” class SecondClass { public: void otherFunc() { FirstClass y; FirstClass b[10]; y.someFunc(); return(y); } private: FirstClass x; FirstClass a[10]; }; Last Topic: Knowing WHEN to Include .H Files Here are the rules… You must include the header file (containing the full Why? Because C++ needs toof a class) definition know the class’s details in order to define actual variables Any time… with it or to let you call methods from 1. You define a regular variable it! of that class’s type, OR 2. You use the variable in any way (call a method on it, return it, etc). On the other hand…
  • 51. A.h class FirstClass { Last Topic: Knowing This line tells C++ that your WHEN to Include .H Files class exists, but doesn’t actually public: void someFunc() { ... the gory details. define all } If you do NONE of the Since none of this code actually but you… previous items, }; B.h class FirstClass; class SecondClass { uses the “guts” of the class (as // enough! 1. Use the class the code did on the previous to define a parameter to slide), this is all C++ needs to a function, OR know!Use the class as the 2. public: void goober(FirstClass p1); FirstClass hoober(int a); void joober(FirstClass &p1); void koober(FirstClass *p1); void loober() { FirstClass *ptr; } private: FirstClass *ptr1, *z[10]; }; return type for a func, OR 3. Use the class to define a pointer or reference variable Then you DON’T need to include the class’s .H file. (You may do so, but you don’t need to) Instead, all you need to do is give C++ a hint that your class exists (and is defined elsewhere). Here’s how you do that:
  • 52. A.h class FirstClass { … // public:thousands of lines …voidthousands of{lines} // someFunc() ... }; B.h #include “A.h” // really slow! class SecondClass { public: private: }; Last Topic: Knowing WHEN to Include .H Files Wow – so confusing! Why not just always use #include to avoid the confusion? There are two reasons: 1. If a .h file is large (thousands of lines), #including it when you don’t strictly need to slows down your compilation! 2. If two classes refer to each other, and both classes try to #include the other’s .H file, you’ll get a compile error.
  • 53. Students and Classrooms Every student knows what class he/she is in… Every class has a roster of its students… CS 32 Kerry Cyril Kerry Cyril Math 31b Lydia Hal Lydia Hal These type of cyclical relationships cause #include problems!
  • 54. Last Topic: Self-referential Classes And here we have the Student refersto thethat each Student Since our Student classclass. Note Student class, HereSince ouraClassRoomclass refers holds aclassroomclass we have ClassRoomclass the problem? bunch of Students… Do you see that to the knows whichincludes ClassRoom.h… in… it classroom he or she it includes Student.h is Student.h ClassRoom.h #include “ClassRoom.h” #include “Student.h” class Student { public: ... class ClassRoom { public: ... private: ClassRoom *m_myRoom; }; private: Student m_studs[100]; }; Student.cpp ClassRoom.cpp #include “Student.h” #include “ClassRoom.h” void Student::printMyClassRoom() { cout <<“I’m in Boelter #” << m_myRoom->getRmNum(); } void ClassRoom::printRoster() { for (int i=0;i<100;i++) cout << m_studs[i].getName(); }
  • 55. Last Topic: Self-referential Classes main.cpp #include “Student.h” Student.h #include “ClassRoom.h” class Student { public: ... private: The compiler will keep ClassRoom }; going forever!!!!! *m_myRoom; ClassRoom.h #include “Student.h” int main() { Student david; … } class ClassRoom { public: ... private: Student m_studs[100]; };
  • 56. So how do we solve this cyclical nightmare? Step #1: Look at the two class definitions in your .h files. At least one of them should NOT need the full #include. Question: This our JUST defines a pointer Which ofclass two classes doesn’t need the full #include? Why? to a ClassRoom. It does NOT hold a full ClassRoom variable and therefore doesn’t require the full class definition here!!! Student.h This class defines actual Student variables… It therefore requires the full class definition to work! ClassRoom.h #include “ClassRoom.h” #include “Student.h” class Student { public: ... class ClassRoom { public: ... private: ClassRoom *m_myRoom; }; private: Student m_studs[100]; };
  • 57. So how do we solve this cyclical nightmare? Step #2: Take the class that does NOT require the full #include (forget the other one) and update its header file: Replace the #include “XXXX.h” statement with the following: class YYY; Where YYY is the other class name (e.g., ClassRoom). Student.h ThisThe Compiler says: line tells ClassRoom.h the compiler: The Programmer says: “Alright smartypants, I’ll trust you. #includeCompiler replies: The “Student.h” “I think I’ll have a little fun! Let’s“Hey Compiler, there’s “Wannt playclass called class Student what the compiler says ifclass ClassRoom me about But if won’t tell another nasty? Ok. see {I are 9000 SYNTAX ERRORS { Here define a full variable!”ClassRoom’s functions and variables ‘ClassRoom’ but we’re not public: public: for deal with!” ... can’t goingyou to define any actual …then you to tell you exactly ... whatvariables like just yet.” it looks with it X #include “ClassRoom.h” class ClassRoom; private: ClassRoom *m_myRoom;, haha; }; private: Student m_studs[100]; or }; any member functions on it.” call
  • 58. So how doAll you need is this we solve this cyclical nightmare? class declaration; line to give the compiler a heads-up. Step #3: Almost done. Now update the CPP file for this class by #including the other header file normally. Since this .H file JUST has a pointer to a ClassRoom (but no This line tells the compiler: code in this file that uses or defines #include So you must a full ClassRoom variable)… “Hey Compiler, since my CPP its header file here! file is going to actually Student.h use class’s functionality, I’ll #include “ClassRoom.h” You’re calling a member tell you all the details class ClassRoom; now The Compiler says: function of ClassRoom about the class.” Student.cpp class Student here… #include “Student.h” { #include public: “ClassRoom.h” void Student::printMyClassRoom() ... { cout <<“I’m in Boelter #” << private: m_myRoom->getRmNum(); ClassRoom *m_myRoom; } }; Ah, ok, now I can see the full definition of what a ClassRoom Thevariable reallyhappy as compiler is is… long as you #include the Feel free to call its getRmNum() classmethod if you like! you definition before actually use the class in your functions…
  • 59. So how do we solve this cyclical nightmare? The Compiler says: Step #4: Finally, make sure that your Hey! Wait a second, you’re Student.h calling the getRmNum( ) class doesn’t have any other #include “ClassRoom.h” class ClassRoom; function but you haven’t defined member functions that violate class Student the full class. No WAY! our #include vs class rules… { public: void beObnoxious() { void beObnoxious(); … Fix it or DIE! cout << m_myRoom->getRmNum() << “ sucks!”; } private: ClassRoom *m_myRoom; }; If you have defined one or more functions DIRECTLY in Alright. That’s better. your class definition AND they Student.cpp use your other class in a #include “Student.h” Don’t let it happen again. significant way, then you must #include “ClassRoom.h” void Student::printMyClassRoom() MOVE them to the CPP file. The Compiler says: {void Student::beObnoxious() { cout << m_myRoom->getRmNum() << “ sucks!”; } cout <<“I’m in Boelter #” << m_myRoom->getRmNum(); }
  • 60. So how do we solve this cyclical nightmare? Now let’s look at both of our classes… Notice, we no longer have a cyclical reference! Woohoo! Student.h #include “ClassRoom.h” class ClassRoom; ClassRoom.h #include “Student.h” class Student { public: ... class ClassRoom { public: ... private: ClassRoom *m_myRoom; }; private: Student m_studs[100]; }; Student.cpp #include “Student.h” #include “ClassRoom.h” void Student::printMyClassRoom() { cout <<“I’m in Boelter #” << m_myRoom->getRmNum(); } ClassRoom.cpp #include “ClassRoom.h” void ClassRoom::printRoster() { for (int i=0;i<100;i++) cout << m_studs[i].getName(); }
  • 61. Class Challenge RULES • The class will split into left and right teams • One student from each team will come up to the board • Each student can either – write one new line of code to solve the problem OR – fix a single error in the code their teammates have already written • Then the next two people come up, etc. • The team that completes their program first wins! Team #1 VOID float FUNC() int Team #2 int func(int * v) int { while(v > 0)
  • 62. Challenge #1 Write a class called quadratic which represents a second-order quadratic equation, e.g.: 4x2+3x+5 When you construct a quadratic class, you pass in the three coefficients (e.g., 4, 3, and 5) for the equation. The class also has an evaluate method which allows you pass in a value for x. The function will return the value of f(x). The class has a destructor which prints out “goodbye”
  • 63. Challenge #2 Write a class called MathNerd which represents a math nerd. Every MathNerd has his own special quadratic equation! When you construct a MathNerd, he always wants you to specify the first two coefficients (for the x2 and x) for his equation. The MathNerd always selects a value of PI for his final coefficient. The MathNerd had a getMyValue function which accepts a value for x and should return f(x) for the nerd’s QE.

Editor's Notes

  1. Philip Wadler. He invented the “Haskell” language.