22.2.  Polymorphism and virtual Destructors

[ fromfile: inheritance-detail.xml id: virtualdestructors ]

Example 22.3. 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 22.4. 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;
};
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 22.5. 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;
}

1

getName() is virtual.


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

[ . . . . ]

int main() {
  QString listing;
   {                                                   1
      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);        2
      bnk << a4;
      listing = bnk.getAcctListing();
    }                                                  3
    qDebug() << listing;
    qDebug() << "Now exit program" ;
} 

1

Begin internal block.

2

What's this?

3

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


Closing Acct - sending e-mail to primary acctholder:Gene Kelly
Closing Acct - sending e-mail to primary acctholder:Fred Astaire
Closing Acct - sending e-mail to primary acctholder:Gene Kelly
Closing Acct - sending e-mail to primary acctholder:Gene Kelly
[ ... ]
Closing Acct - sending e-mail to primary acctholder:Gene Kelly
Closing Joint Acct - sending e-mail to joint acctholder:Ginger Rodgers
Closing Acct - sending e-mail to primary acctholder:Fred Astaire
Closing Joint Acct - sending e-mail to joint acctholder:Leslie Caron
Closing Acct - sending e-mail to primary acctholder:Gene Kelly
Closing Joint Acct - sending e-mail to joint acctholder:Leslie Caron
Closing Acct - sending e-mail to primary acctholder:Gene Kelly
[ ... ]
[Note]Note

If you declare one or more virtual methods in a class, you should define a virtual destructor for that class, even if it has an empty body.



[88] Compilers report a missing virtual in the destructor as a warning, and the behavior is undefined, so you may not see the same thing on your system.