Free Web Hosting Provider - Web Hosting - E-commerce - High Speed Internet - Free Web Page
Search the Web

June 15, 1999

PSBC Topics:    64-71

 

 

 

 

OVERVIEW

Morning

Afternoon

 

NOTES

Handouts from today

Announcements

Acronyms and Abbreviations

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

68.     Virtual functions

69.     Polymorphism

70.     Late (dynamic) binding

71.     Pointer or reference & virtual functions

 

Morning

a.  Edmund’s Review

 

Afternoon

a.  PSBC topic #’s 64-71

 

Handouts

a.        CookieMonster.cpp Demo

b.       Class list + feedback from Stephen regarding study partners and groups

 

Announcements

 None

 

Acronyms and Abbreviations

 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 =

 

PSBC Topic #’s 64-71
 
Hiding

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

 

EXAMPLE #1

 

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( )

                BooToo( )  : y(13) { }                           //could’ve written BooToo( ):y(13) {Boo::y = 10;}…it’s a possibility

};

 

Text Box: HIDING
**The answer is 14 because any derived function that has the same name as the base function, hides that base function.  Thus, the functions, f(float ff) and f( ) are hidden and int f(int) is called.

Note:  
If int f (int) was missing from class BooToo, then there would be a compiler error since int f( ) doesn’t take any arguments.  If int f( ) wasn’t in class BooToo either, then the f function calls in Boo would be evaluated.
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)

 

Code reuse

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 functions

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

 
 


                                                                                                                                                Class DIAGRAM

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


//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

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 (dynamic) binding

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.