多态
- 默认情况下,父类指针指向子类对象,只能调用父类中的函数。
Animal *p = new Dog
指针p
只能调用Animal类
中的函数
#include <iostream>
using namespace std;
class Animal {
public:
int m_age;
void speak() {
cout << "animal speak()" << endl;
}
void run() {
cout << "animal run()" << endl;
}
};
class Cat:public Animal {
public:
int m_live;
void speak() {
cout << "cat speak()" << endl;
}
void run() {
cout << "cat run()" << endl;
}
};
class Dog :public Animal{
public:
void speak() {
cout << "dog speak()" << endl;
}
void run() {
cout << "dog run()" << endl;
}
};
int main() {
Animal* p = new Dog();
p->run();
p->speak();
cout << "-------------" << endl;
Cat* p1 = (Cat *)new Dog();
p1->run();
p1->speak();
p1->run();
return 0;
}
多态的实现
Animal* p1 = new Cat();
p1->speak();
mov eax,dword ptr [p1]
mov edx,dword ptr [eax]
mov eax,dword ptr [edx]
call eax
p1->run();
mov eax,dword ptr [ebp-8]
mov edx,dword ptr [eax]
mov eax,dword ptr [edx+4]
call eax
多态与重载
void fun(Animal *p){
p->speak();
}
void fun(Animal *p){
p->speak();
}
void fun(Cat *p){
p->speak();
}
总结
- 多态的要素
子类重写父类的成员函数(override)
父类指针指向子类对象
利用父类指针调用重写的成员函数 - 多态
同一操作作用与不同对象,可以有不同的解释,产生不同的结果。
父类指针指向子类对象。多态:函数调用与子类对象类型有关;非多态:函数调用与父类指针类型有关。
将指针存放的地址给eax(对象的地址),取出对应的虚函数指针给edx(对象的前四个字节),根据虚函数的不同计算不同的偏移[edx+4] ,最后call这个地址。 - 虚函数表
- 继承父类的
重写了,自己类的虚函数
没有重写,父类中的虚函数 - 自己类中新增的virtual
- 不同情况的虚函数表
父是父的虚函数表,子是子的虚函数表。不要混为一谈。
单继承:B继承A,C继承B。只有一张虚函数表。
多继承:C继承A,C继承B。有两张虚函数表,C中自己新增的放在先继承的表中。
菱形继承中顶层属性重复,用虚继承解决。子类会生成两张表;两个父类会生成一张表;爷爷类没有表。
虚继承中夹杂虚函数。子类最多有四张表。