// File: C++Example/inherit.C // demo of constructors, destructors, inheritance, etc. #include using namespace std; class base { public: int size; int *data_arr; // gets allocated by constructor base (int n) : size(n) { cout << "base constructor with arg: " << n << endl; data_arr = new int[n]; } ~base() { cout << "base destructor" << endl; delete [] data_arr; } base() : size(10) { cout << "base constructor without arg" << endl; data_arr = new int[10]; } base(const base& b) // this constructor makes a new object as a copy of b { cout << "base copy constructor" << endl; size = b.size; data_arr = new int[size]; for(int i=0; idata_arr and b.data_arr will point to // the same array (which may not be desired) // b) on destruction, the array is deleted twice // (which may cause a run-time error) // Note: if you really want to share objects, you must // keep track of a reference count before deleting them { cout << "base assignment operator: COPIES ARRAY" << endl; if (this != &b ) // guard against self assignment {size = b.size; delete [] data_arr; data_arr = new int[size]; for(int i=0; i(d)), it(d.it) // implements the default copy constructor // only written to print on its invocation { cout << "derive copy constructor" << endl; } derive& operator=(const derive& d) // implements default assignment operator // only written to print on its invocation { cout << "derive assignment operator" << endl; if( this != &d) {static_cast(*this) = static_cast(d); // alternatively: base::operator=(static_castd); it = d.it; } return *this; } friend ostream& operator<<(ostream&, const derive&); }; ostream& operator<<(ostream& os, const derive& d) {os << "write derive obj to stream: " << endl << " " << static_cast(d) << endl << " " << d.it; return os; } int main(int argc, char *argv[]) { // 1. explicity create a derive object // (this object must be explicity deleted) cout << "1. new derive(5,20);" << endl; derive* d1_ptr; d1_ptr = new derive(5,20); cout << *d1_ptr << endl << endl; // 2. create a derive object in an automatic variable // (which will be deleted as soon as the var goes out of scope) cout << "2. derive d2;" << endl; derive d2; cout << d2 << endl << endl; // 3. assign a derive object to another cout << "3. d2 = *d1_ptr;" << endl; d2 = *d1_ptr; cout << d2 << endl << endl; // 4. create a derive object by copy through "initialization" cout << "4. derive d3 = d2;" << endl; derive d3 = d2; // Note: same as derive d3(d2); [NOT operator=] cout << d3 << endl << endl; // 5. assign to base object an expression whose type matches // the type of a constructor parameter cout << "5. base b; b = 4;" << endl; base b1; b1 = 4; // Note: such an implicit conversion can be disallowed by // declaring in class base: explicit base(int); cout << b1 << endl << endl; // 6. invoke the derive destructor cout << "6. delete d1_ptr;" << endl; delete d1_ptr; cout << endl; // 7. various implict destructors will be invoked before returning cout << "The end" << endl; return 0; }