虚函数表之多继承有函数覆盖

时间:2021-08-31 08:07:22
								
	多继承有函数覆盖							
								
	struct Base1							
	{							
	public:							
	    virtual void Fn_1()							
	    {							
	        printf("Base1:Fn_1...\n");							
	    }							
	    virtual void Fn_2()							
	    {							
	        printf("Base1:Fn_2...\n");							
	    }							
	};							
	struct Base2							
	{							
	public:							
	    virtual void Fn_3()							
	    {							
	        printf("Base2:Fn_3...\n");							
	    }							
	    virtual void Fn_4()							
	    {							
	        printf("Base2:Fn_4...\n");							
	    }							
	};							
	struct Sub:Base1,Base2				
	{							
	public:							
	    virtual void Fn_1()							
	    {							
	        printf("Sub:Fn_1...\n");							
	    }							
	    virtual void Fn_3()							
	    {							
	        printf("Sub:Fn_3...\n");							
	    }							
		virtual void Fn_5()						
	    {							
	        printf("Sub:Fn_5...\n");							
	    }							
	};							
	int main(int argc, char* argv[])							
	{							
		//查看 Sub 的虚函数表						
	    Sub sub;							
								
		//通过函数指针调用函数,验证正确性						
	    typedef void(*pFunction)(void);							
								
								
		//对象的前四个字节是第一个Base1的虚表						
		printf("Sub 的虚函数表地址为:%x\n",*(int*)&sub);						
								
		pFunction pFn;						
								
		for(int i=0;i<6;i++)						
		{						
			int temp = *((int*)(*(int*)&sub)+i);					
			if(temp == 0)					
			{					
				break;				
			}					
			pFn = (pFunction)temp;					
			pFn();					
		}						
								
		//对象的第二个四字节是Base2的虚表						
		printf("Sub 的虚函数表地址为:%x\n",*(int*)((int)&sub+4));						
								
		pFunction pFn1;						
								
		for(int k=0;k<2;k++)						
		{						
			int temp = *((int*)(*(int*)((int)&sub+4))+k);					
			pFn1 = (pFunction)temp;					
			pFn1();					
		}						
								
		return 0;						
	}

虚函数表之多继承有函数覆盖

上面示例代码中,子类sub的sub:Fn_1、sub:Fn_3、sub:Fn_5,与父类base1、base2,先覆盖,后继承,也就是说编译器第一步,会先用子类和所有的父类的比较,有相同的就会把子类虚函数覆盖到父类虚表中。第二步,注意,不相同的子类虚函数会贴在第一个父类虚表后面的位置。

1.平时不建议使用多继承,代码的维护会比较麻烦,尽量使用多重继承。

2.多继承有时,除了子类继承第一个父类虚表外,其它继承过来的父类都会单独有一张虚表,也就是虚表会有多个。

3.有覆盖多继承时,子类的虚函数覆盖哪个父类的虚函数,就存在哪个父类的虚表中。(子类虚函数覆盖哪个父类,就在哪个父类的虚表中)。