//Inheritance4.h 的內容 #include <string> #include <memory> using namespace std; enum class Discipline { ARCHEOLOGY, BIOLOGY, COMPUTER_SCIENCE }; enum class Classification { FRESHMAN, SOPHOMORE, JUNIOR, SENIOR }; class Person { protected: string name; public: Person() { setName(""); } Person(const string& pName) { setName(pName); } void setName(const string& pName) { name = pName; } string getName() const { return name; } }; class Student:public Person { private: Discipline major; shared_ptr<Person> advisor; public: Student(const string& sname, Discipline d, const shared_ptr<Person>& adv) : Person(sname) { major = d; advisor = adv; } void setMajor(Discipline d) { major = d; } Discipline getMajor() const { return major; } void setAdvisor(shared_ptr<Person> p) { advisor = p; } shared_ptr<Person> getAdvisor() const { return advisor; } }; class Faculty :public Person { private: Discipline department; public: Faculty(const string& fname, Discipline d) : Person(fname) { department = d; } void setDepartment(Discipline d) { department = d; } Discipline getDepartment() const { return department; } }; class TFaculty : public Faculty { private: string title; public: TFaculty(const string& fname, Discipline d, string title):Faculty(fname, d) { setTitle(title); } void setTitle (const string& title) { this->title = title; } // Override getName() string getName() const { return title + " " + Person::getName(); } }; //main主程式 // This exhibits the default non-polymorphic behavior of C++. #include "inheritance4.h" #include <vector> #include <iostream> using namespace std; int main() { // Create a vector of pointers to Person objects vector<shared_ptr<Person>> people { make_shared<TFaculty> ("Indiana Jones", Discipline::ARCHEOLOGY, "Dr."), make_shared<Student>("Thomas Cruise", Discipline::COMPUTER_SCIENCE, nullptr), make_shared<Faculty>("James Stock", Discipline::BIOLOGY),make_shared<TFaculty>("Sharon Rock", Discipline::BIOLOGY, "Professor"), make_shared<TFaculty>("Nicole Eweman", Discipline::ARCHEOLOGY, "Dr.") }; // Print the names of the Person objects for (int k = 0; k < people.size (); k++) { cout << people[k]->getName() << endl; } return 0; }程式輸出結果:
Indiana Jones
Thomas Cruise
James Stock
Sharon Rock
Nicole Eweman
people[k]->getName();
該函數用於檢索要列印的名稱。在每次呼叫中,指向基礎類別 Person 的指標 people[k] 用於呼叫不同派生類的物件中的 getName 函數。其中的一些類,如 TFaculty,提供了更特殊化的版本來覆蓋 getName 函數。當 people[k] 指向 TFaculty 物件時,編譯器必須在 Person 中定義的 getName 與 TFaculty 中定義的 getName 之間進行選擇。Person 是指標所屬的類,TFaculty 是物件實際所屬的類。class B { public: void mfun() { cout << "Base class version"; } }; class D : public B { public: void mfun() { cout << "Derived class version"; } }; shared_ptr<Base> ptr = make_shared<D>();根據前面的介紹可知,此時如果寫入以下語句,那麼將被呼叫的應該是基礎類別 B 的成員函數而不是派生類 D 的成員函數:
ptr->mfun()
如果想讓編譯器選擇使用派生類 D 中更特殊化的 mfun() 版本,那該怎麼辦呢?在 C++ 中,可以通過將 mfun() 宣告為基礎類別中的虛擬函式來執行此操作。C++ 中使用虛擬函式來支援多型行為。因此,為了實現基礎類別 B 及其所有派生類中 mfun() 函數的多型行為,必須修改基礎類別 B 中的定義如下:class B { public: virtual void mfun() { cout << "Base class version"; } };虛擬特性是可繼承的。即如果派生類的成員函數覆蓋了基礎類別中的虛擬函式,那麼該成員函數也會自動虛擬它本身。因此,在基礎類別 B 中將 mfun 宣告為虛擬函式,也將使 D 以及所有從 D 中派生的類中的 mfun 函數變成虛擬函式。
class D : public B { public: virtual void mfun() { cout << "Derived class version"; } };在本範例中,虛擬函式己經定義在類宣告中。如果虛擬函式定義在類宣告之外,則 virtual 關鍵字將繼續對其類中宣告有效,而對定義無效。C++ 不允許在類外面定義虛擬函式時加 virtual 關鍵字。
//Inheritance5.h 的內容 #include <string> #include <memory> using namespace std; enum class Discipline { ARCHEOLOGY, BIOLOGY, COMPUTER_SCIENCE }; enum class Classification { FRESHMAN, SOPHOMORE, JUNIOR, SENIOR }; class Person { protected: string name; public: Person() { setName(""); } Person(const string& pName) { setName(pName); } void setName(const string& pName) { name = pName; } //virtual function virtual string getName() const { return name; } }; class Student:public Person { private: Discipline major; shared_ptr<Person> advisor; public: Student(const string& sname, Discipline d, const shared_ptr<Person>& adv) : Person(sname) { major = d; advisor = adv; } void setMajor(Discipline d) { major = d; } Discipline getMajor() const { return major; } void setAdvisor(shared_ptr<Person>& p) { advisor = p; } shared_ptr<Person> getAdvisor() const { return advisor; } }; class Faculty :public Person { private: Discipline department; public: Faculty(const string& fname, Discipline d) : Person(fname) { department = d; } void setDepartment(Discipline d) { department = d; } Discipline getDepartment() const { return department; } }; class TFaculty : public Faculty { private: string title; public: TFaculty(const string& fname, Discipline d,const string& title):Faculty(fname, d) { setTitle(title); } void setTitle (const string& title) { this->title = title; } // Override getName() string getName() const { return title + " " + Person::getName(); } }; //main主程式 // This exhibits the default non-polymorphic behavior of C++. #include "inheritance5.h" #include <vector> #include <iostream> using namespace std; int main() { // Create a vector of pointers to Person objects vector<shared_ptr<Person>> people { make_shared<TFaculty> ("Indiana Jones", Discipline::ARCHEOLOGY, "Dr."), make_shared<Student>("Thomas Cruise", Discipline::COMPUTER_SCIENCE, nullptr), make_shared<Faculty>("James Stock", Discipline::BIOLOGY),make_shared<TFaculty>("Sharon Rock", Discipline::BIOLOGY, "Professor"), make_shared<TFaculty>("Nicole Eweman", Discipline::ARCHEOLOGY, "Dr.") }; // Print the names of the Person objects for (int k = 0; k < people.size (); k++) { cout << people[k]->getName() << endl; } return 0; }程式輸出結果:
Dr. Indiana Jones
Thomas Cruise
James Stock
Professor Sharon Rock
Dr. Nicole Eweman