New blog location
New blog location
class Base { public: void fooMethod(); protected: string mProtectedString; private: double mPrivateDouble; }
class Derived: public Base { public: void aNewMethod(); }
Base and they would be siblings of Derived. The Base class has no idea about the Derived class. A pointer or reference to Base could actually be pointing at a Derived. For example, the following code is valid:Base* b = new Derived();
b. Derived class has access to public and protected members of the base class. To prevent inheritance, one can mark a class as final. In order to override methods of the base class in a derived class, they must be marked virtual. It is a good rule of thumb to mark every method except the constructor virtual.override in the .h file of the derived class at the end like so:class Derived: public Base { public: virtual void fooMethod() override; }
Base reference to a Derived object, the correct method is called.Derived der; Base& baseRef = der; baseRef.fooMethod(); //calls the Derived version
Base method:Derived der; Base b = der; b.fooMethod(); //Calls the base version
virtual implementationvirtual methods, a vtable is used as follows:class Base { public: virtual void virtFunc1() {} virtual void virtFunc2() {} void regularFunc() {} } class Derived : public Base { public: virtual void virtFunc2() override {} void regularFunc() {} } Base base; Derived der;
Base *p = new Derived; delete p; //Base dtor is called, but not the derived destructor.
final to prevent inheriting from it.virtual void foo() final;
static data members are constructed in the order in which they were declared.int Derived::foo() { return Base::foo() + 2; }
Base& base = derived;
CheckingAccount classclass CheckingAccount { public: virtual void deposit(double amount); virtual void withdraw(double amount); virtual double getBalance(); private: static double dollarsToPounds(double dollars); static double poundsToDollars(double pounds); double mAccountBalance; std::string mAccountNumber; };
CheckingAccountDollarsCheckingAccount and PoundsCheckingAccount are sibling derived classes that derive from CheckingAccount base class. The properties of this scenario are:CheckingAccount objects without knowing whether it is a DollarsCheckingAccount or a PoundsCheckingAccount.virtual methods, the appropriate method is called.Bank class can contain a collection of multi-typed objects (using CheckingAccount objects).CheckingAccount base classclass CheckingAccount { public: virtual void deposit(double amount); virtual void withdraw(double amount); virtual double getBalance(); };
=0. Here is the CheckingAccount class now:class CheckingAccount { public: virtual ~CheckingAccount() = default; virtual void deposit(double amount) = 0; virtual void withdraw(double amount) = 0; virtual double getBalance() = 0; virtual std::string getAccountNumber(); private: double mAccountBalance; std::string mAccountNumber; }; std::string CheckingAccount::getAccountNumber() { return mAccountNumber; }
std::unique_ptr<DollarsCheckingAccount> = make_unique<DollarsCheckingAccount>(1000.00,"1234");
DollarsCheckingAccount can be defined as follows:class DollarsCheckingAccount : CheckingAccount { public: virtual void deposit(double amount) override; virtual void withdraw(double amount) override; virtual double getBalance() override; }; //mAccountBalance and the values passed in are dollars. void DollarsCheckingAccount::deposit(double amount) { mAccountBalance += amount; } void DollarsCheckingAccount::withdraw(double amount) { if((mAccountBalance - amount) > 0) { mAccountBalance -= amount; } } double DollarsCheckingAccount::getBalance() { return mAccountBalance; }
PoundsCheckingAccount can be defined as follows:class PoundsCheckingAccount : CheckingAccount { public: virtual void deposit(double amount) override; virtual void withdraw(double amount) override; virtual double getBalance() override; private: static double dollarsToPounds(double dollars); static double poundsToDollars (double pounds); } void PoundsCheckingAccount::deposit(double amount) { double poundsValue = dollarsToPounds(amount); mAccountBalance += poundsValue; } void PoundsCheckingAccount::withdraw(double amount) { double poundsValue = dollarsToPounds(amount); if((mAccountBalance - amount) > 0) { mAccountBalance -= amount; } } void PoundsCheckingAccount::getBalance() { double dollarsValue = poundsToDollars(mAccountBalance); return dollarsValue; }
vector of accounts can be made:vector<unique_ptr<CheckingAccount>> accountsVector;
DollarsCheckingAccount or PoundsCheckingAccount will be called:accountsVector.push_back(make_unique<DollarsCheckingAccount>(1000.00,"1234")); accountsVector.push_back(make_unique<PoundsCheckingAccount>(1000.00,"5678")); accountsVector.push_back(make_unique<DollarsCheckingAccount>(2000.00,"9101112")); accountsVector[0]->deposit(1000.00); accountsVector[1]->withdraw(500.00);
class DollarsCheckingAccount: CheckingAccount { public: DollarsCheckingAccount(double balance, string accountNumber); DollarsCheckingAccount(const PoundsCheckingAccount& poundsCheckingAccount); //converting constructor }
DollarsCheckingAccount::DollarsCheckingAccount(const PoundsCheckingAccount& poundsCheckingAccount) { mAccountBalance = poundsCheckingAccount.getBalance(); //getBalance auto converts to dollars. mAccountNumber = poundsCheckingAccount.getAccountNumber(); }
DollarsCheckingAccount might be as follows:DollarsCheckingAccount operator+(const DollarsCheckingAccount& lhs, const DollarsCheckingAccount& rhs) { DollarsCheckingAccount newAct(0.0,"<unique_account_number>"); newAct.deposit(lhs.getBalance() + rhs.getBalance()); return newAct; }
DollarsCheckingAccount the above operator will work. Given the converting constructor above, the following will work:PoundsCheckingAccount pndsAct(1000.00,"1234"); pndsAct.deposit(500.00); DollarsCheckingAccount dlrsAct = pndsAct + pndsAct;
= operator, a default copy constructor and assignment operator will be provided for the derived class's data members and the base class copy constructor and assignment operator will be used for the base class's data members. If you do specify a copy constructor and assingment operator in derived class, you need to call the base class versions:class Base { public: virtual ~Base() = default; Base() = default; Base(const Base& src); }; Base::Base(const Base& src) { } class Derived : public Base { public: Derived() = default; Derived(const Derived& src); }; Derived::Derived(const Derived& src) : Base(src) { } Derived& Derived::operator=(const Derived& rhs) { if (&rhs == this) { return *this; } Base::operator=(rhs); // Calls parent's operator=. // Do necessary assignments for derived class. return *this; }
Comments
Post a Comment