CSC 213 Code Chapter 7, Fall 2007

Notre Dame University–Louaize · Program Design and Data Abstraction II · 4 pages

All CSC 213 files
CSC 213 Code Chapter 7, Fall 2007, page 1

Stuck on a question? A tutor can walk you through it.

CSC 213 Code Chapter 7, Fall 2007, page 2 CSC 213 Code Chapter 7, Fall 2007, page 3 CSC 213 Code Chapter 7, Fall 2007, page 4

More CSC 213 files

Show the text of this file
Classes Part II 1 ! Data Member declared as constant. • Data member of a class can also be declared as constant… // Using a member initializer to initialize a constant of a built-in // data type. #include <iostream.h> class Increment { public: Increment( int c = 0, int i = 1 ); void print() const; private: int count; const int incVal; // const data member }; // Constructor for class Increment with initializer for const member Increment::Increment( int c, int i) { count = c; incVal = i[JAN1]; } // Print the data void Increment::print() const { cout << "count = " << count << ", incVal = " << incVal << endl; } void main() { Increment value( 10, 5 ); value.print(); } Syntax Error Classes Part II 2 • Constant data members of an object, must be given a value at construction time… • A member initializer is used to provide the constructor with a value of that const data member of the declared object… // Using a member initializer to initialize a constant of a built-in // data type. #include <iostream.h> class Increment { public: Increment( int c = 0, int i = 1 ); void addIncrement() { count += incVal; } void print() const; private: int count; const int incVal; // const data member }; // Constructor for class Increment with initializer for const member Increment::Increment( int c, int i) : incVal( i)[JAN2] { count = c; } // Print the data void Increment::print() const { cout << "count = " << count << ", incVal = " << incVal << endl; } Classes Part II 3 // Using a member initializer to initialize a constant of a built-in // data type. #include <iostream.h> class Increment { public: Increment( int c = 0, int i = 1 ); void addIncrement() { count += incVal; } void print() const; private: int count; const int incVal; // const data member }; // Constructor for class Increment with initializer for const member Increment::Increment( int c, int i) : incVal( i)[JAN3] { count = c; } // Print the data void Increment::print() const { cout << "count = " << count << ", incVal = " << incVal << endl; } void main() { Increment value( 10, 5 ); cout << "Before incrementing: "; value.print(); for ( int j = 0; j < 3; j++ ) { value.addIncrement(); cout << "After increment " << j + 1 << ": "; value.print(); } } Classes Part II 4 • Multiple member initializers … #include <iostream.h> class More { public: More ( int c = 0, int i = 1, int j = 2 ); void Print() const { cout << count << " " << Val_1 << " " << Val_2 << " "; } private: int count; const int Val_1; const int Val_2; }; // Constructor for class Increment with multiple initializer. More::More( int c, int i, int j) : Val_1(i), Val_2(j)[JAN4] { count = c; } void main() { More One( 10, 5, 3 ); One.Print(); } Classes Part II 5 • Any data members can be initialized using member initializer syntax #include <iostream.h> class All { public: All ( int c, int i, int j, int k); void Print() const { cout << count << " " << Ndx << " " << Val_1 << " " << Val_2; } private: int count; int Ndx; const int Val_1; const int Val_2; }; All::All( int c, int i, int j, int k) : Ndx (k), Val_1( i ), Val_2( j )[JAN5] { count = c; } void main() { All One( 10, 5, 3 ,1); One.Print(); } Classes Part II 6 Composition: Objects as Members of Classes • Sometime, a class data member is an object of another class… This is Composition. H Haass__AA Employee Date_of_birth Date_of_hire Date Classes Part II 7 • Example: Private data member as an object of another class. class cA { public: cA(int j=1) { setX(j); } void setX(int i) { x=i;} int getX() { return x; } private: int x; }; class cB { public: cB(int j=2, int k=3) : objA(k)[JAN6] { setY(j); } void setY(int i) { y=i; } int getY() { return y;} int getObj() { return objA.getX(); } private: int y; cA objA; }; void main() { cA a1; cB b1; cout << a1.getX() << endl; cout << b1.getObj() << endl; cout << b1.getY() << endl; } Classes Part II 8 • Example: Public data member as an object of another class. class cA { public: cA(int j=1) { setX(j); } void setX(int i) { x=i;} int getX() { return x; } private: int x; }; class cB { public: cB(int j=2, int k=3) : objA(k) { setY(j); } void setY(int i) { y=i; } int getY() { return y;} int getObj() { return objA.getX(); } cA objA; private: int y; }; void main() { cA a1; cB b1; cout << a1.getX() << endl; cout << b1.getY() << endl; b1.objA.setX(30);[JAN7] cout << b1.objA.getX() << endl; cout << b1.getObj() << endl; } Classes Part II 9 • Example: o Member objects are constructed in order of their declaration in the class …(Not in order of constructor’s member initializer list) o Inner objects are constructed first and destructed last… class cA { public: cA[JAN8](int j=1) { setX(j); cout << "Constructor class cA:" << x << endl; } ~cA[JAN9]() { cout << "Destructor class cA:" << x << endl; } void setX(int i) { x=i;} private: int x; }; class cB { public: cB[JAN10](int j=2, int k=3,int m=5):objA2(m), objA1(k){ setY(j); cout << "Constructor class cB:" << y << endl; } ~cB[JAN11]() { cout << "Destructor class cB: << y << endl; } void setY(int i) { y=i;} private: int y; cA objA1; cA objA2; }; void main() { cB b1; cout << "Order of construction/destruction\n"; } Classes Part II 10 friend Functions and friend Classes • A friend function of a class is defined outside that class’s scope, yet has the right to access private and protected members of the class… • A friend class is a class whose member functions have access to the other class's private and protected members… • Friendship is granted, not taken… • Not symmetric… If B a friend of A, A not necessarily a friend of B… • Not transitive … if A a friend of B, B a friend of C, A not necessarily a friend of C… Classes Part II 11 • friend function // fig07_05.cpp // Friends can access private members of a class. #include <iostream.h> // Modified Count class class Count { friend [JAN12]void setX( Count &[JAN13], int ); // friend declaration public: Count() { x = 0; } // constructor void print() const { cout<< x <<endl; } private: int x; // data member }; // Can modify private data of Count because // setX is declared as a friend function of Count void setX( Count &c, int val ) { c.x = val; // legal: setX is a friend of Count } int main() { Count counter; cout << "counter.x after instantiation: "; counter.print(); cout << "counter.x after call to setX friend function: "; setX( counter, 8 ); // set x with a friend counter.print(); return 0; } Classes Part II 12 • friend class #include <iostream.h> class A { friend class B;[JAN14] public: A (int a) { setA(a);} void setA (int a) { valA = a; } void printA() { cout <<"valA is " <<valA <<endl;} private: int valA; }; class B { public: B (int b) { setB(b);} void setB (int b) { valB = b; } void incA( A &[JAN15] a ) {a.valA++;} void printB() { cout <<"valB is " <<valB <<endl;} void printAnB(A &[JAN16] a) { cout <<"valA printed in B is " <<a.valA << endl; cout << "valB is " << valB << endl; } private: int valB; }; void main() { A a1(10); B b1(5); a1.printA(); b1.printB(); b1.incA(a1); b1.printAnB(a1); } Classes Part II 13 Using the this Pointer • Allows objects to access their own address… • It is not part of the object itself… Thus it is not reflected in the results of a sizeof operation on the object… • When a nonstatic member function is called for an object, the address of the object is passed (By the compiler) as a hidden argument to the function… The object's address is available from within the member function as the this pointer… void Date::setMonth( int mn ) { month = mn; // These three statements this->month = mn[JAN17]; // are equivalent (*this).month = mn[JAN18]; } • The type of the this pointer depends upon the type of the object and whether the member function using this is constant or non-constant… object * const const object * const Classes Part II 14 // fig07_07.cpp:Using the this pointer to refer to object members. #include <iostream.h> class Test { public: Test( int = 0 ); void setX( int); void print() const; private: int x; }; Test::Test( int a ) { x = a; } void Test::setX( int a) { x = a; this[JAN19]->x =a; ( *this ).x = a; } void Test::print() const { cout << " x = " << x << "\n this[JAN20]->x = " << this->x << "\n(*this).x = " << ( *this ).x << endl; } void main() { Test testObject( 12 ); testObject.print(); testObject.setX( 50 ); testObject.print(); } const Test * const Test * const Classes Part II 15 return *this; • The this pointer can be used for Cascaded member function calls... • When a function returns a reference pointer to the same object Other functions can operate on that pointer… #include <iostream.h> class A { public: A (int a) { setA(a);} A &[JAN21] setA (int a) { valA = a; return *this[JAN22]; } A & incA() { valA++; return *this; } void printA() { cout <<"valA is " <<valA <<endl; } private: int valA; }; void main() { A a1(10); a1.printA(); a1.setA(20).printA();[JAN23] a1.setA(50).incA().printA();[JAN24] } Classes Part II 16 #include <iostream.h> class A { public: A (int a) { setA(a);} A & setA (int a) { valA = a; return *this; } A *[JAN25] incA() { valA++; return this[JAN26]; } void printA() { cout <<"valA is " <<valA <<endl; } private: int valA; }; void main() { A a1(10); a1.printA(); a1.setA(20).printA(); a1.setA(50).incA()->printA(); } Classes Part II 17 Dynamic Memory Allocation with Operators new and delete • The new and delete operators provide a superior means to allocate memory than the “ ANSI C “ malloc and free … • ANSI C : TypeName *typeNamePtr; ... typeNamePtr = malloc ( sizeof ( TypeName ) );[JAN27] ... free ( typeNamePtr ); ... • C++ : TypeName *typeNamePtr; ... typeNamePtr = new TypeName;[JAN28] ... delete typeNamePtr; ... • Creates an object of the proper size, calls its constructor and returns a pointer of the correct type… • If there is insufficient memory for the allocation request, it returns NULL ( 0 ) pointer… Classes Part II 18 #include <iostream.h> #include <string.h> void main () { int *iPtr; float *fPtr ; char *cArrPtr ; fPtr = new float (3.1416); iPtr = new int; *iPtr = 129; cout << iPtr << " - " << *iPtr <<endl; delete iPtr; iPtr = new int [4]; iPtr[2]=10; cout << iPtr[2] << endl; cArrPtr = new char [30] ; strcpy (cArrPtr,"This is a test"); cout << cArrPtr << endl; delete [ ] cArrPtr;[J29] delete fPtr; delete [ ] iPtr; } • Space created with new sshhoouulldd nnoott be released (freed) with free and space created with malloc sshhoouulldd nnoott be released with delete… • Since C++ programs can contain storage created with malloc / free and new / delete… It is best to use only new / delete ... Classes Part II 19 • Using new to dynamically create an object of a class will automatically invokes the class’s constructor… delete will automatically invokes the class’s destructor… #include <iostream.h> class A { public: A (int a=0) { setA(a); printA(); } void setA (int a) { valA = a; } void printA() { cout <<"valA is " <<valA <<endl; } ~A () { cout << "Destructor "; printA(); } private: int valA; }; void main () { A *aPtr; aPtr = new A (10); delete aPtr; aPtr = 0;[J30] aPtr = new A [2];[JAN31] delete [ ] aPtr; aPtr = 0; } Classes Part II 20 static Class Members • Each object of a class has its own copy off all the data members of the class… • To share a data member by all object of a class, we need to use a static class member… #include <iostream.h> class A { public: A (int a) { setA(a); incCntA(); } void setA (int a) { valA = a; } void incCntA () {countA++; } void decCntA () {countA--; } void printA() { cout <<"valA is " <<valA <<endl; cout <<"countA is " <<countA <<endl; } ~A () { cout << "Destructor "; decCntA(); printA(); } private: int valA; static int countA;[JAN32] }; Classes Part II 21 • Efficient when a single copy of data is enough … Only the static variable has to be updated • May seem like global variables, but have class scope… only accessible to objects of same class • Must be initialized once (only) at file scope… Otherwise, it is a syntax error… (Linker) int A::countA = 0;[JAN33] void main () { A a1( 10 ), a2( 20 ); a1.printA(); cout << “ Out of main…” << endl; } • Static data members exist, even if no instances (objects) of the class exist… Classes Part II 22 • Both variables and functions can be static… They can be public, private or protected… • public static variables are accessible through any object of the class… They can also be accessed thought the class name using the binary scope resolution operator… #include <iostream.h> class A { public: static int countA; A (int a) { setA(a); } void setA (int a) { valA = a; } private: int valA; }; int A::countA=0; void main () { A a1(10); A a2(20); cout << a1.[J34]countA << endl; cout <<a2.countA << endl; A::[J35]countA=10; cout <<A::countA << endl; cout <<a2.[J36]countA << endl; } Classes Part II 23 • private and protected static variables must be accessed through a public member function… • static member functions cannot access non-static data or functions… • public static member function can be called thought by the class name using the binary scope resolution operator… #include <iostream.h> class A { public: A (int a) { valA = a; } void incCntA () {countA++; } static void decCntA () { countA--; countA = valA + 1; } private: int valA; static int countA; }; int A::countA=0; void main () { A a1(10); a1.incCntA(); A::decCntA(); } Syntax Error