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; };
CheckingAccount
DollarsCheckingAccount
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