6.5.  Constructors, Destructors, and Copy Assignment Operators

[ fromfile: derivedcdas.xml id: derivedcdas ]

  1. Copy constructors

  2. Copy assignment operators

  3. Destructors

[Important] Why Are These Functions Special?

The base class functions are not sufficient to initialize, copy, or destroy a derived instance.

Constructors

Order of Initialization

Initialization proceeds in the following order:

  1. Base classes first, in the order in which they are listed in the classHead of the derived class

  2. Data members, in declaration order

Copy Assignment Operators

Copy Constructors

Example 6.20. src/derivation/assigcopy/account.h

[ . . . . ]

class Account {
 public:
    Account(unsigned acctNum, double balance, QString owner);
    virtual ~Account(){
      qDebug() << "Closing Acct - sending e-mail " 
               << "to primary acctholder:" << m_Owner; }
    virtual QString getName() const {return m_Owner;}
    // other virtual functions
 private:
    unsigned  m_AcctNum;
    double    m_Balance;
    QString    m_Owner;
};

Example 6.21. src/derivation/assigcopy/account.h

[ . . . . ]

class JointAccount : public Account {
 public:
  JointAccount (unsigned acctNum, double balance, 
                QString owner, QString jowner);
  JointAccount(const Account & acct, QString jowner);
  ~JointAccount() {
     qDebug() << "Closing Joint Acct - sending e-mail "
              << "to joint acctholder:" << m_JointOwner; }
  QString getName() const { 
    return QString("%1 and %2").arg(Account::getName())
                   .arg(m_JointOwner);
  }
  // other overrides
 private:
  QString m_JointOwner;
};

Example 6.22. src/derivation/assigcopy/account.cpp

[ . . . . ]

Account::Account(unsigned acctNum, double balance, QString owner) :
     m_AcctNum(acctNum), m_Balance(balance), m_Owner(owner)
    { }

JointAccount::JointAccount (unsigned acctNum, double balance,
                            QString owner, QString jowner)
    :Account(acctNum, balance, owner),
     m_JointOwner(jowner)   1
     { }

JointAccount::JointAccount (const Account& acc, QString jowner)
    :Account(acc),          2
     m_JointOwner(jowner)
    { }

1

Base class initialization required.

2

Compiler-generated copy constructor call.


Example 6.23. src/derivation/assigcopy/bank.h

[ . . . . ]
class Account;

class Bank {
 public:
    Bank& operator<< (Account* acct); 1
    ~Bank();
    QString getAcctListing() const;
 private:
    QList<Account*> m_Accounts;
};
[ . . . . ]

1

This is how to add object pointers to m_Accounts.


Example 6.24. src/derivation/assigcopy/bank.cpp

[ . . . . ]
#include <QDebug>
#include "bank.h"
#include "account.h"

Bank::~Bank() {
    qDeleteAll(m_Accounts);
    m_Accounts.clear();
}


Bank& Bank::operator<< (Account* acct) {
   m_Accounts << acct;
   return *this;
}

QString Bank::getAcctListing() const {
   QString listing("\n");
   foreach(Account* acct, m_Accounts)  
      listing += QString("%1\n").arg(acct->getName()); 1
   return listing;
}
int main() {
  QString listing;
   {                                                   2
      Bank bnk;
      Account* a1 = new Account(1, 423, "Gene Kelly");
      JointAccount* a2 = new JointAccount(2, 1541, "Fred Astaire",
         "Ginger Rodgers");
      JointAccount* a3 = new JointAccount(*a1, "Leslie Caron");
      bnk << a1;
      bnk << a2;
      bnk << a3;
      JointAccount* a4 = new JointAccount(*a3);        3
      bnk << a4;
      listing = bnk.getAcctListing();
    }                                                  4
    qDebug() << listing;
    qDebug() << "Now exit program" ;
} 
[ . . . . ]

1

getName() is virtual.

2

Begin internal block.

3

What's this?

4

At this point, all four Accounts are destroyed as part of the destruction of the bank.


Destructors