没有多态的时候
class father{
public:
int a;
void fun1(){
cout<<"father";
}
};
class son:public father{
public:
int b;
void fun1(){
cout<<"son";
}
};
int main(){
son s;
father *f = &s;
f->fun1();//输出father
cout<<sizeof(*f);//输出4,只包含father的对象所占内存
}
将son的对象的地址给f,可f还是father的对象指针,仅仅用了father的对象所占的内存;
加入多态和类的大小
class father{
public:
virtual void fun1(){
cout<<"father";
}
};
class son:public father{
public:
int b;
void fun1(){
cout<<"son";
}
};
class son1:public father{
public:
int b;
virtual void fun2(){
cout<<"son";
}
virtual void fun3(){
cout<<"son";
}
};
int main(){
son s;
father *f = &s;
father f1;
f->fun1();//输出son
son1 s1;
cout<<sizeof(f1)<<endl;//输出8,64位指针为8位,虚指针
cout<<sizeof(*f)<<endl;//输出8,说明f还是father类,只包含father的内存
cout<<sizeof(s)<<endl;//输出16,son继承成了父类的虚指针8个字节,加上int b的4个字节,内存对齐
cout<<sizeof(s1)<<endl;//输出16,继承的父类虚指针和自身的虚指针
}
多态的底层原理
早绑定
普通的函数,在编译的时候就已经把函数地址绑定在对象上了。
动态绑定
有虚函数的类,创建一个虚表,存放虚函数的地址。
创建一个虚指针指向虚表。
当父类的指针指向子类的指针时,虚指针初始化,指向子类的虚表
何时虚指针初始化
子类在创建对象的时候,先执行父类的构造函数,此时只看到父类。
再执行子类的构造函数,子类的虚指针被初始化。
虚函数
父类定义虚函数virtual void fun(){}
子类定义void fun(){},还是虚函数,无需写virtual