——派生類須要本身的構造函數。函數
派生類中能夠根據須要添加額外的數據成員和成員函數,甚至能夠給予繼承的原成員函數新的定義。this
基類指針或引用可指向派生對象,反過來則只能使用強制類型轉換。spa
派生類對象可以使用基類的非私有成員。指針
可以使用派生對象初始化基類對象或賦值。code
通常不容許將基類對象賦給派生類對象(上面第三條),特殊狀況下能夠。對象
已有派生類對象初始化建立的派生類對象。blog
已有派生類對象給另外一個派生類對象賦值。繼承
派生類對象的析構函數被調用後會自動調用基類的析構函數。內存
C++11增長了容許繼承構造函數的機制,但派生類默認不能繼承構造函數和析構函數。ci
class RatedPlayer : public TableTennisPlayer { private: unsigned int rating; // add a data member public: RatedPlayer (unsigned int r = 0, const string &fn = "none", const string &ln = "none", bool ht = false); RatedPlayer (unsigned int r, const TableTennisPlayer &tp); unsigned int Rating() const { return rating; } // add a method void ResetRating (unsigned int r) { rating = r; } // add a method };
構造函數必須給新成員和繼承的成員提供數據。
RatedPlayer::RatedPlayer(unsigned int r, const string &fn, const string &ln, bool ht) : TableTennisPlayer(fn, ln, ht) { rating = r; }
派生類對象過時時,程序將首先調用派生類析構函數,而後再自動調用基類析構函數。
要使用派生類,程序必需要能訪問基類聲明。
派生類對象可使用基類的方法,條件是方法不是私有的(即公有和保護)。
基類指針能夠在不進行顯示類型轉換的狀況下指向派生類對象;基類引用能夠在不進行顯示類型轉換的狀況下引用派生類對象
RatedPlayer rplayer(1140, "Mallory", "Duck", true); TableTennisPlayer &rt = rplayer; TableTennisPlayer *pt =&rplayer; rt.Name(); // invoke Name() with reference pt->Name(); // invoke Name() with pointer
不能夠將基類對象和地址賦給派生類引用和指針,除非使用強制轉換(友元函數不是成員函數所以不能被繼承,但欲使用基類的友元函數時可以使用此方法,但要當心用錯)。
基類聲明的函數引用參數或指針參數可用於值爲基類對象或派生類對象以及它們的地址的狀況。
void Show(const TableTennisPlayer &rt) { ... }
TableTennisPlayer player1("Tara", "Boomdea", false); RatedPlayer rplayer1(1140, "Mallory", "Duck", true); Show(player1); // works with TableTennisPlayer argument Show(rplayer1); // works with RatedPlayer argument
省略形參爲const TableTennisPlayer *rt的狀況,與上類似。
引用兼容性屬性:能夠將基類對象初始化爲派生類對象。
RatedPlayer olaf1(1840, "Olaf", "Loaf", true); TableTennisPlayer olaf2(olaf1);
匹配的構造函數的原型:
TableTennisPlayer(const RatedPlayer &); // doesn't exit
類中並無該構造函數,但存在隱式複製構造函數:
// implicit copy constructor TableTennisPlayer(const TableTennisPlayer &);
即它將olaf2初始化爲嵌套在RatedPlayer對象olaf1中的TableTennisPlayer對象(使用派生類中嵌套的基類對象對目標基類對象進行初始化)
一樣,也能夠將派生對象賦給基類對象:
RatedPlayer olaf1(1840, "Olaf", "Loaf", true); TableTennisPlayer winner; winner = olaf1; // assign derived to base object
在這種狀況下,程序使用隱式重載賦值運算符:
TableTennisPlayer &operator=(const TableTennisPlayer &) const;
與上相似,使用派生類中嵌套的基類對象對目標基類對象進行按成員賦值。
特殊的用基類對象給派生類對象賦值的狀況
若是派生類包含了將基類對象轉換爲派生類對象的構造函數,或派生類定義了將基類對象賦給派生類對象的賦值運算符,則能夠用派生類對象給基類對象賦值。
用已有的派生類對象初始化建立的派生類對象
複製類成員或繼承的類組件時,則是使用該類的複製構造函數完成的,對於繼承的基類對象來講也是合適的。
用已有的派生類對象給另外一個派生類對象賦值
按成員賦值,調用類成員賦值運算符,使用基類的賦值運算符來對基類組件(繼承的基類對象)進行賦值
若派生類使用了動態內存分配,派生類的析構函數、複製構造函數、複製運算符都必須使用相應的基類方法來處理基類元素(顯示調用基類構造函數和複製運算符):
hasDMA &hasDMA::operator=(const hasDMA &has) { if (this == &hs) return *this; baseDMA::operator=(hs); // copy base portion ... return *this; }
---