(注:以下的运行环境是vs2008)
【虚表的定义】:
1.1定义:
1.2理解的关键点:
【虚表的创建】:
1)基类(虚表):按照虚函数在基类中出现的先后次序进行一次逐个填写虚表地址。
2)派生类(虚表):
A、先要知道基类虚表的格式
B、派生类对基类中那些虚函数进行重写,如果重写了,会将虚表中相同偏移位置的函数的地址进行重写
C、再将最后四个字节写为0
注意:
1、 不同对象的虚表地址相同
2、 基类类型的指针指向派生类对象,要调用派生类重写的函数时,无法调用
【不同继承方式下不同情况的虚表】:
2.1单继承的无重写的虚表
1)说明:程序的结果:
A:基类的打印自己的,派生类的也打印自己的
B:基类大小:如果有成员的话,就是成员加头四个字节(指向虚表的指针)派生类大小;如果有成员的话,就是成员加基类加指向虚表的指针
2)举例代码:
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class Derived:public Base
{
public:
Derived()
{}
virtual void fun3()
{
cout<<"Derived::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Derived::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Derived::fun5()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
Derived d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"Derived::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&d);
while(*pn)
{
(*pn)();
pn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程序的运行结果图:
2.2单继承的有重写的虚表
1)说明:程序的结果:
基类依然打印自己的,派生类将基类对应偏移位置的覆盖掉
2)举例代码:
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class Derived:public Base
{
public:
Derived()
{d = 10;}
virtual void fun0()
{
cout<<"Derived::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Derived::fun1()"<<endl;
}
virtual void fun5()
{
cout<<"Derived::fun5()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
Derived d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"Derived::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&d);
while(*pn)
{
(*pn)();
pn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)运行程序结果
1)程序运行结果说明:
A:基类打印自己的,派生类只打印自己的,并不会打印基类的
B:基类大小:不变
派生类大小:要加一个偏移量,所以多八个字节
依次是:指向派生类的虚表指针,偏移量,派生类的数据成员,
指向基类的虚表指针,基类的数据成员
2)举例代码:
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class Derived:virtual public Base
{
public:
Derived()
{d = 20;}
virtual void fun3()
{
cout<<"Derived::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Derived::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Derived::fun5()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
Derived d;
//Base* p = &d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"Derived::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&d);
while(*pn)
{
(*pn)();
pn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程序运行结果:
4)对象模型分析:
2.4单继承的虚拟继承的有重写的虚表
1)程序结果分析:
A:基类打印的不变,派生类将重写的不打印,只打印自己的
B:基类大小:不变
派生类的大小:和无重写的几乎一样,不过多了一个用于区分对象的0
这个0加在了派生类数据成员和指向基类虚表的指针之间,
这就是多出来的四个字节
2)举例代码:
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class Derived:virtual public Base
{
public:
Derived()
{d = 20;}
virtual void fun0()
{
cout<<"Derived::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Derived::fun1()"<<endl;
}
virtual void fun5()
{
cout<<"Derived::fun5()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
Derived d;
//Base* p = &d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"Derived::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&d);
while(*pn)
{
(*pn)();
pn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)代码运行结果:
4)对象模型分析
2.5多继承的无重写的虚表
1)程序运行结果说明:
A:基类1:打印自己的
B: 基类2:打印自己的
C:派生类:打印基类一,打印自己的
D:大小:基类大小不变,派生类大小是基类一加基类2加自己的数据成员大小
2)举例代码:
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:public Base1,public Base2
{
public:
Derived()
{d = 30;}
virtual void fun6()
{
cout<<"Derived::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"Derived::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*((int *)(&d)+2);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)代码运行结果
4)对象模型说明
2.6多继承的有重写的虚表
1)程序运行结果说明:
A: 执行结果:派生类覆盖了基类的,其他不变
B: 大小:同上
2)举例代码:
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:public Base1,public Base2
{
public:
Derived()
{d = 30;}
virtual void fun0()
{
cout<<"Derived::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Derived::fun1()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
4)对象模型解析
这个我就不做过多的分析了。
2.8多继承的虚拟继承的无重写的虚表(虚拟继承一个基类)
1)程序运行结果说明:
A:基类打印:基类打印自己的
B:大小:多了偏移量,多了四个字节
2)举例代码:
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:virtual public Base1,public Base2
{
public:
Derived()
{d = 30;}
virtual void fun6()
{
cout<<"Derived::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"Derived::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)代码运行结果:
4)
2.9多继承的虚拟继承的无重写的虚表(虚拟继承所有的基类)
1)程序运行结果分析
A:基类打印:基类打印自己的,派生类只打印自己的
B:大小:多了偏移量,多了八个字节
2)举例代码
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:virtual public Base1,virtual public Base2
{
public:
Derived()
{d = 30;}
virtual void fun6()
{
cout<<"Derived::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"Derived::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程序运行结果
4)对象模型分析
2.10多继承的虚拟继承的有重写的虚表(虚拟继承一个基类)
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:virtual public Base1,public Base2
{
public:
Derived()
{d = 30;}
virtual void fun0()
{
cout<<"Derived::fun0()"<<endl;
}
virtual void fun4()
{
cout<<"Derived::fun4()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程序运行结果
4)对象模型说明
2.11多继承的虚拟继承的有重写的虚表(虚拟继承所有的基类)
1)程序运行结果说明:
A:基类不变,派生类重写的不打印,只打印自己的
B:大小:重写的话,重写几个就多几个字节,多了一个用于区分的零在B1和D之间
2)举例代码:
#include<iostream>
using namespace std;
class Base1
{
public:
Base1()
{
b=10;
}
virtual void fun0()
{
cout<<"Base1::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base1::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base1::fun2()"<<endl;
}
int b;
};
class Base2
{
public:
Base2()
{
b=20;
}
virtual void fun3()
{
cout<<"Base2::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"Base2::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"Base2::fun5()"<<endl;
}
int b;
};
class Derived:virtual public Base1,virtual public Base2
{
public:
Derived()
{d = 30;}
virtual void fun0()
{
cout<<"Derived::fun0()"<<endl;
}
virtual void fun7()
{
cout<<"Derived::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"Derived::fun8()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base1 b1;
Base2 b2;
Derived d;
//Base* p = &d;
cout<<"Base1::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b1);
while(*n)
{
(*n)();
n++;
}
cout<<"Base2::vpf"<<endl;
vpf* pn = (vpf*)*(int *)(&b2);
while(*pn)
{
(*pn)();
pn++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base1)<<endl;
cout<<sizeof(Base2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程序运行结果
2.12无重写普通的菱形继承
1)程序运行结果分析:
A:不过加了虚函数,这时D内存结果是顺序继承:B,C1,C2,D,
(但是在C1和C2之间多了一个地址和一个数据。我的编译器是这样)
B: D执行结果:打印出基类B,基类C1,D
C:执行结果的大小:28
2)举例代码:
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class C1:public Base
{
public:
C1()
{
c1=20;
}
virtual void fun3()
{
cout<<"C1::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"C1::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"C1::fun5()"<<endl;
}
int c1;
};
class C2:public Base
{
public:
C2()
{
c2=30;
}
virtual void fun6()
{
cout<<"C2::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"C2::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"C2::fun8()"<<endl;
}
int c2;
};
class Derived:public C1,public C2
{
public:
Derived()
{
d = 40;
}
virtual void fun9()
{
cout<<"Derived::fun9()"<<endl;
}
virtual void fun10()
{
cout<<"Derived::fun10()"<<endl;
}
virtual void fun11()
{
cout<<"Derived::fun11()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
C1 c1;
C2 c2;
Derived d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"C1::vpf"<<endl;
vpf* pn1 = (vpf*)*(int *)(&c1);
while(*pn1)
{
(*pn1)();
pn1++;
}
cout<<"C2::vpf"<<endl;
vpf* pn2 = (vpf*)*(int *)(&c2);
while(*pn2)
{
(*pn2)();
pn2++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(C1)<<endl;
cout<<sizeof(C2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)代码运行结果
2.13无重写(只有一个直接基类的此处为C1)普通的菱形继承
1)程序运行结果分析
A:D 的打印结果:打印C1,打印D
当然C1的大小多了八个字节
B:执行结果的大小36
2)举例代码
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class C1:virtual public Base
{
public:
C1()
{
c1=20;
}
virtual void fun3()
{
cout<<"C1::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"C1::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"C1::fun5()"<<endl;
}
int c1;
};
class C2:public Base
{
public:
C2()
{
c2=30;
}
virtual void fun6()
{
cout<<"C2::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"C2::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"C2::fun8()"<<endl;
}
int c2;
};
class Derived:public C1,public C2
{
public:
Derived()
{
d = 40;
}
virtual void fun9()
{
cout<<"Derived::fun9()"<<endl;
}
virtual void fun10()
{
cout<<"Derived::fun10()"<<endl;
}
virtual void fun11()
{
cout<<"Derived::fun11()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
C1 c1;
C2 c2;
Derived d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"C1::vpf"<<endl;
vpf* pn1 = (vpf*)*(int *)(&c1);
while(*pn1)
{
(*pn1)();
pn1++;
}
cout<<"C2::vpf"<<endl;
vpf* pn2 = (vpf*)*(int *)(&c2);
while(*pn2)
{
(*pn2)();
pn2++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(C1)<<endl;
cout<<sizeof(C2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程序运行结果
2.13无重写(所有的直接基类都虚拟继承)普通的菱形继承
1)程序运行结果分析
A:和上面的几乎一样,不同的是C2必然多了八个字节
2)举例代码;
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
b=10;
}
virtual void fun0()
{
cout<<"Base::fun0()"<<endl;
}
virtual void fun1()
{
cout<<"Base::fun1()"<<endl;
}
virtual void fun2()
{
cout<<"Base::fun2()"<<endl;
}
int b;
};
class C1:virtual public Base
{
public:
C1()
{
c1=20;
}
virtual void fun3()
{
cout<<"C1::fun3()"<<endl;
}
virtual void fun4()
{
cout<<"C1::fun4()"<<endl;
}
virtual void fun5()
{
cout<<"C1::fun5()"<<endl;
}
int c1;
};
class C2:virtual public Base
{
public:
C2()
{
c2=30;
}
virtual void fun6()
{
cout<<"C2::fun6()"<<endl;
}
virtual void fun7()
{
cout<<"C2::fun7()"<<endl;
}
virtual void fun8()
{
cout<<"C2::fun8()"<<endl;
}
int c2;
};
class Derived:public C1,public C2
{
public:
Derived()
{
d = 40;
}
virtual void fun9()
{
cout<<"Derived::fun9()"<<endl;
}
virtual void fun10()
{
cout<<"Derived::fun10()"<<endl;
}
virtual void fun11()
{
cout<<"Derived::fun11()"<<endl;
}
int d;
};
typedef void (*vpf)();
void Printvpf()
{
Base b;
C1 c1;
C2 c2;
Derived d;
cout<<"Base::vpf"<<endl;
vpf* n = (vpf*)*(int *)(&b);
while(*n)
{
(*n)();
n++;
}
cout<<"C1::vpf"<<endl;
vpf* pn1 = (vpf*)*(int *)(&c1);
while(*pn1)
{
(*pn1)();
pn1++;
}
cout<<"C2::vpf"<<endl;
vpf* pn2 = (vpf*)*(int *)(&c2);
while(*pn2)
{
(*pn2)();
pn2++;
}
cout<<"Derived::vpf"<<endl;
vpf* ppn = (vpf*)*(int *)(&d);
while(*ppn)
{
(*ppn)();
ppn++;
}
cout<<sizeof(Base)<<endl;
cout<<sizeof(C1)<<endl;
cout<<sizeof(C2)<<endl;
cout<<sizeof(Derived)<<endl;
}
int main()
{
Printvpf();
return 0;
}
3)程序运行结果
最后要说明的:还有一些情况类似于上面的,我就不一一说明了,我写的都是比较经典的情况,希望能对大家有所帮助!