123 Main Street
Hometown, 12345
class StreetAddress { private: string line1, line2; public: void setLine1(string); void setLine2(string); string getLine1(); string getLine2(); };因為一個人的資料包含一個姓名和一個街道地址,所以正確表示一個人的資料的類將使用以下方式的組合:
class PersonData { private: string name; StreetAddress address; public: ... };
PemmData 的類宣告中忽略了其餘部分,因為那些與我們要闡述的主旨無關。
在這裡可以使用繼承而不是組合來定義這個類。例如,可以定義一個類 PersonData1,如下所示:class PersonData1:public StreetAddress { private: string name; public: };雖然這個新的定義能夠正確編譯,但從概念上講這其實是錯誤的,因為它將一個人的資料視為一種特殊的街道地址,而事實並非如此。這種型別的設計概念錯誤可能會導致程式理解困擾並難以維護。
class Dog { protected: double weight; public: Dog(double w) { weight = w; } virtual void bark() const { cout << "I am dog weighing " << weight << " pounds." << endl; } };這個類還有一個建構函式,允許 Dog 物件被初始化。請注意,以上範例中已經宣告了一個虛成員函數 bark(),以允許它在派生類中被覆蓋。
class SheepDog:public Dog { private: int numberSheep; public: SheepDog(double w, int nSheep) : Dog(w) { numberSheep = nSheep; } virtual void bark() const override { cout << "I am a sheepdog weighing " << weight << " pounds nand guarding " << numberSheep << " sheep." << endl; } };為了演示該類,可以建立一個狗的向量,向量中的一些狗就是牧羊犬。為了規避向量不能擁有兩種不同型別的事實,可以使用指向 Dog 的指標的向量。前面講過,一個指向基礎類別(在本範例中即 Dog 類)的指標也可以指向任何派生類物件(在本範例中為 SheepDog)。因此,可以建立一個指向 Dog 的指標向量,並且其中一些指標指向 Dog 物件,而另一些指標則指向 SheepDog 物件。
vector<shared_ptr<Dog>> kenne1 { make_shared<Dog>(40.5), make_shared<SheepDog>(45.3, 50), make_shared<Dog>(24.7) };最後,可以使用一個迴圈來呼叫向量中每個 Dog 物件的 bark() 成員函數:
for (int k = 0; k < 3; k++) { cout << k+1 << ": "; kennel[k]->bark(); }由於多型性,並且因為 bark() 函數被宣告為虛擬函式,所以迴圈內的同一行程式碼對普通狗將呼叫原始的 bark() 函數,而對牧羊犬則會呼叫派生類 SheepDog 中的特殊 bark() 函數。完整的程式為:
// This program demonstrates the Is-A relation in inheritance. #include <iostream> #include <memory> #include <vector> using namespace std; // Base class class Dog { protected: double weight; public: Dog(double w) { weight = w; } virtual void bark() const { cout << "I am a dog weighing " << weight << " pounds." << endl; } }; // A SheepDog is a special type of Dog class SheepDog :public Dog { int numberSheep; public: SheepDog(double w, int nSheep) : Dog(w) { numberSheep = nSheep; } void bark() const override { cout << "I am a sheepdog weighing " << weight << " pounds and guarding " << numberSheep << " sheep." << endl; } }; int main() { // Create a vector of dogs vector<shared_ptr<Dog>> kennel { make_shared<Dog>(40.5), make_shared<SheepDog>(45.3, 50), make_shared<Dog>(24.7) }; // Walk by each kennel and make the dog bark for (int k = 0; k < kennel.size(); k++) { cout << k + 1 << ": "; kennel[k]->bark(); } return 0; }程式輸出結果:
1: I am a dog weighing 40.5 pounds.
2: I am a sheepdog weighing 45.3 pounds and guarding 50 sheep.
3: I am a dog weighing 24.7 pounds.