/* Author: Arun Somasundaram, CSE Dept, OSU. Simple Program to test Inheritance Types while deriving classes. Change the values of the inheritance types and see what values can be accessed at the various levels of derived classes. When you change inheritance types, the program could cause errors while compiling. Understand how the inheritance types affect those errors and comment out/change the appropriate statements to compile correctly. This program contains three classes (Mother, Daughter and GrandDaughter) and the main function. g++ -o inheritanceTestExec testInheritanceTypes.cpp */ #include using namespace std; //Base Class class Mother{ private: int mPrv; protected: int mProt; public: int mPub; Mother(); ~Mother(); void printValues(); }; Mother::Mother(){ cout << "Mother's constructor call." << endl; mPrv = 10; mProt = 20; mPub = 30; } Mother::~Mother(){ cout << "Mother's destructor call." << endl; } void Mother::printValues(){ cout << "Mother's " << endl; cout << " mPrv, mProt, mPub " << endl; cout << " " << mPrv << ", " << mProt << ", " << mPub << endl; } //Derived Class - Level 1 //Change the Inheritance types - public/private/protected and test class Daughter:public Mother{ // ^^^^^ change that and test private: int dPrv; protected: int dProt; public: int dPub; Daughter(); ~Daughter(); void dFoo(); void printValues(); }; Daughter::Daughter(){ cout << "Daughter's constructor call." << endl; dPrv = 100; dProt = 200; dPub = 300; } Daughter::~Daughter(){ cout << "Daughter's destructor call." << endl; } void Daughter::printValues(){ cout << "Daughter's... " << endl; cout << " dPrv, dProt, dPub" << endl; cout << " " << dPrv << ", " << dProt << ", " << dPub << endl; Mother::printValues(); //Why is Mother:: needed here? What will happen if that is removed? } void Daughter::dFoo(){ //mPrv = 110; //error why? mProt = 120; mPub = 130; } //Derived Class - Level 2 //Change the Inheritance types - public/private/protected and test class GrandDaughter:public Daughter{ // ^^^^^ change that and test private: int gPrv; protected: int gProt; public: int gPub; GrandDaughter(); ~GrandDaughter(); void gFoo(); void printValues(); }; GrandDaughter::GrandDaughter(){ cout << "GrandDaughter's constructor call." << endl; gPrv = 1000; gProt = 2000; gPub = 3000; } GrandDaughter::~GrandDaughter(){ cout << "GrandDaughter's destructor call." << endl; } void GrandDaughter::gFoo(){ //mPrv = 1010; //error why? mProt = 1020; mPub = 1030; //dPrv = 1100; //error why? dProt = 1200; dPub = 1300; } void GrandDaughter::printValues(){ cout << "GrandDaughter's... " << endl; cout << " gPrv, gProt, gPub " << endl; cout << " " << gPrv << ", " << gProt << ", " << gPub << endl; Daughter::printValues(); //Why is Daughter:: needed here? What will happen if that is removed? } int main(){ //Note the order of call of constructors and destructors Mother m; cout << endl; Daughter d; cout << endl; GrandDaughter g; cout << endl; //m.mProt = 10000; //error why? m.mPub = -10; d.mPub = -100; g.mPub = -1000; m.printValues(); cout << endl; d.printValues(); cout << endl; g.printValues(); cout << endl; cout << "Calling Daughter's dFoo & GrandDaughter's gFoo function" << endl; d.dFoo(); g.gFoo(); d.printValues(); cout << endl; g.printValues(); cout << endl; return 0; }