[英]Base Class Pointer Assigned to Derived Class and Polymorphism
對於以下代碼,將基類指針分配給派生類時,我對多態性有疑問。
當派生類的對象直接使用打印功能時,輸出將顯而易見。
當我使用基類指針並指向派生類的對象時,將使用基類的打印功能,但輸出是派生對象的信息。 誰能詳細解釋原因? 謝謝!
class Person {
public:
Person() {};
Person(string nm):name(nm) {};
void print() const;
private:
string name;
};
class Student : public Person {
public:
Student(int num, string nm) : IDNumber(num), Person(nm) {};
void print() const;
private:
int IDNumber;
}
class Employee : public Person {
public:
Employee(int num, int sal, string nm) : IDNumber(num), salary(sal), Person(nm) {};
void print() const;
private:
int IDNumber, salary;
}
void Person::print() const {
cout << name << endl;
}
void Student::print() const {
cout << "GoGoGo! ";
Person::print();
}
void Employee::print() const {
cout << "I work: ";
Person::print();
}
int main() {
Person per("Peter");
Student stu(3141, "Sally");
Employee emp(2718, 40, "Edward");
Person* ptr = &per;
Person* ptr2 = &stu;
Person* ptr3 = &emp;
per.print(); //Peter
stu.print(); //GoGoGo! Sally
emp.print(); //I work: Edward
ptr->print(); //Peter
ptr2->print(); //Sally
ptr3->print(); //Edward
return 0;
}
函數print()
不是virtual
函數,因此不是多態的。 基類上的函數正在隱藏子類的函數。
使代碼按預期工作的唯一要做的就是在Person
類中將print()
虛擬化:
class Person {
public:
Person() {};
virtual ~Person() {};
Person(string nm):name(nm) {};
virtual void print() const;
private:
string name;
};
請注意,我添加了一個虛擬析構函數,這對於要繼承的每個類都是必需的。
輸出顯示了派生對象的信息,因為子類繼承了基類的成員(即name
,它設置為Peter,Sally和Edward)。
代碼行為的關鍵詞是“靜態綁定和動態綁定”。
當編譯器在編譯時讀取以下語句時,會看到ptr3是Person類型的,它將檢查person類並將print()替換為Person類中定義的print函數地址。 所有這些都發生在編譯時,這就是為什么稱之為靜態綁定。
ptr3->print();
為什么它可以打印通過派生類對象輸入的信息?
在下面的語句中,您將調用基類的構造函數,並在基類成員中輸入信息。 ptr3 *是基類類型,因此它可以訪問其成員。
Employee(int num, int sal, string nm) : IDNumber(num), salary(sal), Person(nm) {};
如果是,則為int薪水; Employee類中的公共成員,並嘗試通過
ptr3->薪水
會報錯
ptr3沒有命名工資的成員
因為薪金是派生類的成員,並且基類對象無法對其進行訪問。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.