一直以来,c++的虚函数以及虚继承令人讨厌。下面通过程序彻底了解c++的虚函数以及虚继承。
#include <iostream>
using namespace std;
//查看虚函数表
classB{};
classB1
{
public:
B1(){cout<<"B1 constructor"<<endl;};//构造函数不能为virtual函数
};
classB2:public B1
{
public:
B2(){cout<<"B2 constructor"<<endl;};//构造函数不能为virtual函数
void f2(){ cout << "B2::f2" << endl; }
};
classB3:public B1
{
public:
B3(){cout<<"B3 constructor"<<endl;};//构造函数不能为virtual函数
void f3(){ cout << "B3::f3" << endl; }
};
classD :public B2,public B3
{
public:
D(){cout<<"D constructor"<<endl;};//构造函数不能为virtual函数
void v3(){ cout << "D::v3" << endl; }
};
//=======================================
int main (int argc,constchar * argv[])
{
cout<<sizeof(B)<<endl;
cout<<sizeof(B1)<<endl;
cout<<sizeof(B2)<<endl;
cout<<sizeof(B3)<<endl;
cout<<sizeof(D)<<endl;
D* d=new D;
B1* b1=new B1;
B2* b2=new B2;
B3* b3=new B3;
d->v3();
return 0;
}
基类中不含虚函数以及不使用虚拟继承时,基类与派生类的size都为1.运行上面的程序,可以看到下面的结果:
继续考虑虚继承对类size的影响。
#include <iostream>
using namespace std;
//查看虚函数表
classB{};
classB1
{
public:
B1(){cout<<"B1 constructor"<<endl;};
};
classB2:publicvirtual B1
{
public:
B2(){cout<<"B2 constructor"<<endl;};
void f2(){ cout << "B2::f2" << endl; }
};
classB3:public virtual B1
{
public:
B3(){cout<<"B3 constructor"<<endl;};
voidf3(){ cout << "B3::f3"<< endl; }
};
classD :public B2,public B3
{
public:
D(){cout<<"D constructor"<<endl;}; void v3(){cout <<"D::v3" <<endl; }
};
//=======================================
intmain (int argc,constchar * argv[])
{
cout<<sizeof(B)<<endl;
cout<<sizeof(B1)<<endl;
cout<<sizeof(B2)<<endl;
cout<<sizeof(B3)<<endl;
cout<<sizeof(D)<<endl;
D* d=new D;
B1* b1=new B1;
B2* b2=new B2;
B3* b3=new B3;
d->v3();
return 0;
}
运行程序,可以看到它的地址表格如下:
继承类虚拟继承基类时,继承类的size变成4,这是为什么???
而考虑菱形结构的虚继承的另外一种方式:
#include <iostream>
using namespace std;
//查看虚函数表
classB{};
classB1
{
public:
B1(){cout<<"B1 constructor"<<endl;};
};
classB2:public B1
{
public:
B2(){cout<<"B2 constructor"<<endl;};
void f2(){ cout << "B2::f2" << endl; }
};
classB3:public B1
{
public:
B3(){cout<<"B3 constructor"<<endl;};
voidf3(){ cout << "B3::f3"<< endl; }
};
classD :public virtual B2,publicvirtual B3
{
public:
D(){cout<<"D constructor"<<endl;}; void v3(){cout <<"D::v3" <<endl; }
};
//=======================================
intmain (int argc,constchar * argv[])
{
cout<<sizeof(B)<<endl;
cout<<sizeof(B1)<<endl;
cout<<sizeof(B2)<<endl;
cout<<sizeof(B3)<<endl;
cout<<sizeof(D)<<endl;
D* d=new D;
B1* b1=new B1;