原理简介:
多态成立的三个条件:
- 存在继承
- 虚函数重写
- 父类指针指向子类对象
之前有看过一个例子:
1 #include <iostream> 2 using namespace std; 3 4 class Father 5 { 6 public: 7 void Face() 8 { 9 cout << "Father's face" << endl; 10 } 11 12 virtual void Say() 13 { 14 cout << "Father say hello" << endl; 15 } 16 }; 17 18 class Son:public Father 19 { 20 public: 21 void Say() 22 { 23 cout << "Son say hello" << endl; 24 } 25 }; 26 27 void main() 28 { 29 Son son; 30 Father *pFather=&son; 31 pFather->Say(); 32 }
总感觉这边可以就在编译的时候确定绑定是哪一个函数,没有必要等到运行时在确定,然后就在思考多态的意义。
后来发现如果代码变成这样时:
1 #include <iostream> 2 using namespace std; 3 4 class Parent 5 { 6 public: 7 virtual void print() 8 { 9 cout<<"父类"<<endl; 10 } 11 }; 12 13 class Child : public Parent 14 { 15 public: 16 virtual void print() 17 { 18 cout<<"子类"<<endl; 19 } 20 }; 21 22 void HowToPlay(Parent *base) 23 { 24 base->print(); 25 } 26 27 int main() 28 { 29 Parent p1; 30 Child c1; 31 HowToPlay(&p1); 32 HowToPlay(&c1); 33 return 0; 34 }
HowToPlay()函数中,传来子类时,执行子类的print函数,传来父类时执行父类的print函数。
于是C++编译器根本不需要区分是子类对象,还是父类对象。父类对象和子类对象分别有vptr指针,先找到虚函数表,再找到函数的入口地址。
这样一种迟绑定的机制可以不需要区分是父类对象还是子类对象,重用base->print()而无需改变。
其实关键是看base指针指向了父类还是子类。