#include #include using namespace std; // class BaseTest // uses a dynamic character array to hold a string. // As a result, it has to implement The Big Three: // destructor, copy constructor, assignment operator= class BaseTest { public: BaseTest() { // Default Constructor test = new char[20]; test[0]='\0'; cout << "\t" << "default constructor BaseTest()" << endl; } BaseTest(const char s[]) { // Construct from a char[] test = new char[strlen(s)+1]; strcpy(test, s); cout << "\t" << "constructor BaseTest(const char s[" << test << "])" << endl; } BaseTest(const BaseTest& bt) { // Copy Constructor test = new char[strlen(bt.test)+1]; strcpy(test, bt.test); cout << "\t" << "constructor BaseTest(copy(" << test << "))" << endl; } ~BaseTest() { // Destructor cout << "\t" << "destructor ~BaseTest(" << test << ")" << endl; delete [] test; } char *get_test() const { return test; } // Accessor void set_test(const char s[]) { // Mutator if (strlen(test) < strlen(s)) { delete [] test; test = new char[strlen(s)+1]; } strcpy(test, s); } BaseTest& operator=(const BaseTest& rhs)// Assignment operator= { cout << "\t" << "BaseTest::operator=(" << rhs.test << ")" << endl; if (this != &rhs) { set_test(rhs.test); } return *this; } // Friend output operator<< friend ostream& operator<<(ostream& out, const BaseTest& test); private: char* test; }; // class DerivedTest // A class to test if the BIG Three are implemented properly in derived // classes. // class DerivedTest : public BaseTest { public: DerivedTest() { cout << "\t" << "DerivedTest(" << get_test() << ")" << endl; } DerivedTest(const char s[]) : BaseTest(s) { cout << "\t" << "DerivedTest(" << get_test() << ")" << endl; } /* // Copy Constructor DerivedTest(const DerivedTest& bt) : BaseTest(bt) { cout << "DerivedTest(copy(" << get_test() << "))" << endl; } */ /* // Assignment Operator DerivedTest& operator=(const DerivedTest& rhs) { BaseTest::operator=(rhs); cout << "DerivedTest::operator=(" << rhs.test << ")" << endl; } */ /* // Destructor ~DerivedTest() { cout << "\t" << "~DerivedTest(" << get_test() << ")" << endl; } */ }; ostream& operator<<(ostream& out, const BaseTest& bt) { cout << "\t" <<"operator<<(ostream&, BaseTest&): " << bt.test; return out; } // showTest(DerivedTest dt) // @param: dt is an instance of DerivedTest to show // @returns: temp is a local is an instance to return. DerivedTest showTest(DerivedTest dt) { DerivedTest temp("myTempTest"); cout << "\t" << "showTest(" << dt.get_test() << ")" << endl; return temp; } int main() { int i = 0; cout << i++ << ": DerivedTest dt;" << endl; DerivedTest dt; cout << i++ << ": DerivedTest dt1(\"MyDerivedTest1\";" << endl; DerivedTest dt1("MyDerivedTest1"); cout << i++ << ": DerivedTest *pt1 = new DerivedTest(\"MyPointerTest\");" << endl; DerivedTest *pdt = new DerivedTest("MyPointerTest"); cout << i++ << ": DerivedTest ddt(\"MyDerivedTest2\");" << endl; DerivedTest ddt("MyDerivedTest2"); cout << i++ << ": BaseTest *pbt = pdt;" << endl; BaseTest *pbt = pdt; cout << i++ << ": delete pbt; // Remember it points to DerivedTest" << endl; delete pbt; cout << i++ << ": showTest(ddt);" << endl; cout << showTest(ddt) << endl; cout << i++ << ": ddt = dt;" << endl; ddt = dt; cout << i++ << ": return 0;" << endl; return 0; }