///////////////////////////////////////////////////////////////////// // override.cpp - demonstrates overloading and overriding // // // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2002 // ///////////////////////////////////////////////////////////////////// #include #include #include ///////////////////////////////////////////////////////////////////// // base class for demonstration of overloading and overriding // class override { public: ///////////////////////////////////////////////////////////////// // constructors are overloaded functions // - overloads have same name, but different argument types override(); override(const std::string &name); override(const override &or); ///////////////////////////////////////////////////////////////// // these virtual functions will be overridden in derived class // - overrides must have exactly the same signature in both // both base and derived classes virtual override* clonePtr(const std::string &name); virtual override& cloneRef(const std::string &name); virtual override cloneObj(const std::string &name); ///////////////////////////////////////////////////////////////// // functions can be both overloaded and overridden as these // demonstrate virtual std::string virtOverload(int x); virtual std::string virtOverload(double d); ///////////////////////////////////////////////////////////////// // overloading in a derived class can hide functions inherited // from the base class, e.g., dor::hide(int) hides overload::hide() virtual std::string hide(); ///////////////////////////////////////////////////////////////// // utility functions demonstrating nothing much at all virtual std::string speak(); std::string& name(); std::string name() const; private: std::string _name; }; // //----< void constructor >------------------------------------------- override::override() : _name("default name") {} //----< promotion constructor >-------------------------------------- override::override(const std::string & name) : _name(name) {} //----< copy constructor >------------------------------------------- override::override(const override &or) : _name(or._name) {} //----< returns pointer to cloned object >--------------------------- override* override::clonePtr(const std::string &name) { return (new override(name)); } //----< returns reference to cloned object >------------------------- override& override::cloneRef(const std::string &name) { return *(new override(name)); } //----< returns cloned object >-------------------------------------- override override::cloneObj(const std::string &name) { override *pOr = new override(name); override temp = *pOr; delete pOr; return temp; } //----< overridden and overloaded member function >------------------ std::string override::virtOverload(int x) { std::ostringstream rtnVal; rtnVal << "This is override::virOverload(int x). Value of x = " << x; return rtnVal.str(); } // //----< overridden and overloaded member function >------------------ std::string override::virtOverload(double x) { std::ostringstream rtnVal; rtnVal << "This is override::virOverload(double x). Value of x = " << x; return rtnVal.str(); } //----< this function will be hidden by derived overload >----------- std::string override::hide() { return "this is override::hide()"; } //----< object identifies itself >----------------------------------- std::string override::speak() { std::ostringstream temp; temp << "this is " << _name << " override object speaking"; return temp.str(); } //----< returns object name reference for reading or writing >------- std::string& override::name() { return _name; } //----< returns name by value for read-only access >----------------- std::string override::name() const { return _name; } // ///////////////////////////////////////////////////////////////////// // derived class for demonstration of overloading and overriding // class dor : public override { public: dor(); dor(const std::string &name); dor(const dor &d); virtual override* clonePtr(const std::string &name); virtual override& cloneRef(const std::string &name); virtual override cloneObj(const std::string &name); virtual std::string virtOverload(int x); virtual std::string virtOverload(double d); virtual std::string hide(int arg); virtual std::string speak(); }; //----< void constructor >------------------------------------------- dor::dor() : override("default name") {} //----< promotion constructor >-------------------------------------- dor::dor(const std::string & name) : override(name) {} //----< copy constructor >------------------------------------------- dor::dor(const dor &or) : override(or.name()) {} //----< returns pointer to cloned object >--------------------------- override* dor::clonePtr(const std::string &name) { return (new dor(name)); } //----< returns reference to cloned object >------------------------- override& dor::cloneRef(const std::string &name) { return *(new dor(name)); } // //----< returned clone is sliced to a base override object type >---- override dor::cloneObj(const std::string &name) { dor *pDor = new dor(name); dor temp = *pDor; delete pDor; return temp; } //----< overridden and overloaded member function >------------------ std::string dor::virtOverload(int x) { std::ostringstream rtnVal; rtnVal << "This is dor::virOverload(int x). Value of x = " << x; return rtnVal.str(); } //----< overridden and overloaded member function >------------------ std::string dor::virtOverload(double x) { std::ostringstream rtnVal; rtnVal << "This is dor::virOverload(double x). Value of x = " << x; return rtnVal.str(); } //----< overloaded virtual function hides override::hide() >--------- std::string dor::hide(int arg) { std::ostringstream rtnVal; rtnVal << "this is dor::hide(int arg). arg = " << arg; return rtnVal.str(); } //----< object identifies itself >----------------------------------- std::string dor::speak() { std::ostringstream temp; temp << "this is " << name() << " dor object speaking"; return temp.str(); } // //----< demonstration >---------------------------------------------- using namespace std; void main() { cout << "\n Demonstrating Overloading and Overriding " << "\n ==========================================\n"; override or1; cout << "\n " << or1.speak(); override *pOr = or1.clonePtr("ptr instance"); cout << "\n " << pOr->speak(); delete pOr; override &rOr = or1.cloneRef("ref instance"); cout << "\n " << rOr.speak(); delete &rOr; cout << "\n " << or1.cloneObj("obj instance").speak(); cout << "\n " << or1.virtOverload(-3); cout << "\n " << or1.virtOverload(3.1415927); cout << "\n " << or1.hide(); cout << "\n\n"; dor dor1; cout << "\n " << dor1.speak(); pOr = dor1.clonePtr("ptr instance"); cout << "\n " << pOr->speak(); delete pOr; override &rOra = dor1.cloneRef("ref instance"); cout << "\n " << rOra.speak(); delete &rOra; //////////////////////////////////////////////////////// // this returned object is sliced to a base type cout << "\n " << dor1.cloneObj("obj instance").speak(); cout << "\n " << dor1.virtOverload(-3); cout << "\n " << dor1.virtOverload(3.1415927); /////////////////////////////////////////////////////////////////////////// // overload::hide() is hidden by dor::hide(int), so this will not compile // cout << "\n " << dor1.hide(); cout << "\n " << dor1.hide(1); cout << "\n\n"; }