Handouts from today
Important concepts or terms not related
to PSBC
PSBC topics covered:
64. Hiding
65. Derivative access (public, protected, private)
66. Code reuse
67. Overriding (not overloading) member functions
69. Polymorphism
71. Pointer or reference & virtual functions
a. Edmund’s Review
a. PSBC topic #’s 64-71
a. CookieMonster.cpp Demo
b. Class list + feedback from Stephen regarding study partners and groups
None
None
Important non-related PSCB concepts
or terms
Two exceptions that types are different:
1. If you pass a char, you really pass an int (don’t really pass a character)
Character gets picked up both as a char and an int happily
2. A float cannot get passed as a float, but you are REALLY passing a double due to hardware limitations (float is converted to a double prior to passing it)
If you pass a float, it gets picked up as a double AND a float function, but if you pass a double, it doesn’t get picked up as a float
ASSIGNMENT vs.
INITIALIZATION OPERATORS
13 Assignment operators
11 using the = sign: =, *=, %=, /=, +=, -=, <<=, >>=,
&=, ^=, |=
2 unary ++ and - -
operators
2 Initializers
( ) and =
Hiding is the relationship between the derived function and the base function such that if the derived function has the same name as the base function, it hides that base function and makes it inaccessible
Class Boo
{
private:
int x;
public:
int Getx( ){return x;}
int y; //this y is (Boo::y) and equals 3
int z;
Boo( ) : x(1), y(3), z(5) { }
int f( ) {return z;}
int f (float ff) {return 3;}
};
class BooToo : public Boo
{
int f (int) {return 14;}
int f ( ) {return 12;}
int y; //this y is
BooToo::y, which equals 13, & is different than y in Boo( )
};
main ( )
{
int k = 111;
BooToo b;
cout << b.x << endl; //CE
cout << b.y << endl; //13
cout << bGetx ( ) << endl; //1
cout
<< b.f(k) << endl; //14
cout
<< b.f( ) << endl; //12
cout
<< b.f(2.0) << endl; //14**
}
Derivative access (public, protected, private)
Gain access through by
one of three methods:
a.
Derivative could be a
friend of the parent (needs object access)
OR
b. Always have an accessor function (inspector/mutator)
up in the base that goes and directly gets what is wanted--
OR
c.
Disambiguation by means
of the scope resolution operator
e.g. int z = b.Boo::y; where y is an object in class Boo
(Note: Can
do an end run/work around where
you write a Boo::y = 10 into
class BooToo to assign y the value of 10 )
In class BooToo, I “AM” a
Boo so even though something may be inaccessible, it can be rewritten
(i.e. Boo::x = 10; is a
legitimate statement in the class BooToo despite int x being private in class
Boo)
The purpose of writing code
in C++ is that others use it. It
should be self-documenting and somewhat documented.
Overriding (not overloading)
member functions
Overriding has two levels
just as hiding has two levels and it provides more than one signature for the
same name or function. In other words,
the function up at the higher level and the same function in the lower level
have signatures that match perfectly (i.e. base and derived functions
respectively have the SAME signature).
The bodies do not have to be the same in order for the function to be
overridden.
Review of overloading:
Remember that overloading always takes place in a single
class or globally (both functions are in the
same class or both functions are global functions).
Class Boo
{
int func ( );
int f (float); /*example
of overloading since two fxns are in the SAME class,
int f
(int); have
the SAME name but different signatures*/
}
Able to take any operator and
overload that operator (provide whole new way to use the operator; a new
meaning)
Virtual means “don’t bind now…don’t figure it out until run-time”. Virtual never applies to an object; it only applies when dealing with pointers and references. These functions have the capacity to use code just for the base and override functions in the child in case the child needs special treatment. Use a pointer to the base and can access both capacities—can slide down to the child class.
Pointer



//Answers are in RED below
main( )
{
Boo b;
Boo *pb1 = new Boo;
BooToo bt;
BooToo *pbt1 = new Boo;
BooToo *pbt2 = new BooToo;
Boo
*pb2 = new BooToo;
Boo &rb = b;
Boo &rbt = bt;
b.f(2); //1
b.f( ); //CE
b.g( ); //3
bt.f(2); //CE
bt.g( ); //33
bt.f(2.0F); //CE
bt.f(3.0); //CE
bt.f( ); //44
b.f( ); //CE
pb1àf(2); //1
pb1àf(2.0F); //2
pb2àf(2); //11
pb2àf(2.0F); //2
pb1àg( ); //3
pb1àf( ); //CE
pb2àf( ); //CE
rb.f(
); //CE
rbt.f(
); //CE
rb.f(2); //1
rbt.f(2); //11
rb.g(
); //3
rbt.g(
); //33
rb.f
(2.0); //CE
rb.f
(2.0F); //2
rbt.f(2.0); //CE
rbt.f(1.0); //CE
rb.f(
); //CE
rbt.f(
); //CE
return
0;
}
Polymorphism occurs ONLY
when a virtual function is called through a pointer or a reference. C never
matches a function call to the appropriate function at runtime whereas this is
automatic and occurs at runtime in C++.
Late or dynamic binding is matching a function call to the appropriate function. It occurs when the following three conditions are met. The function is:
1. a non-static member function …
2. called through a pointer or reference (not directly through an object) …
3. virtual (i.e. it is declared virtual or an override of the same-signature function is declared virtual)
Late binding costs time, as it is done at runtime, and gives your data no protection (privacy is only enforced at compile-time: by runtime it is too late).
Pointer or reference &
virtual functions
For late binding to occur, the virtual function called must
be called through a pointer or reference, and not through an object directly.