c++::详解虚表

(注:以下的运行环境是vs2008)

【虚表的定义】:

1.1定义:

每个有虚函数的类或者虚继承的子类,编译器都会为它生成一个虚表,表中的每一个元素都指向一个虚函数的地址(虚表是从属于类的)

1.2理解的关键点:

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)运行程序结果


2.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多继承的虚拟继承的有重写的虚表(虚拟继承一个基类)

1)程序运行结果说明
      A:基类不变,派生类重写的基类一未影响,二会覆盖
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 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)程序运行结果


最后要说明的:还有一些情况类似于上面的,我就不一一说明了,我写的都是比较经典的情况,希望能对大家有所帮助!吐舌头


  • 9
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值