首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

C++ 多重继承,有没有哦人来说说,该怎么解决

2013-09-05 
C++ 多重继承,有没有哦人来说说只有 father1 放在第一个位置 才能实现多态,貌似 在虚函数表里通过偏移来定

C++ 多重继承,有没有哦人来说说

   

只有 father1 放在第一个位置 才能实现多态,貌似 在虚函数表里通过偏移来定位函数。  今天被这个坑了一把!

C++? 继承 多态
[解决办法]
你fun3这种调用方式相当于调用类中的第一个函数,类似于这样。
int vTable = *(int*)&at;
void (*myFun)() = (void (*)())*(int*)vTable;
myFun();
而类实例的内存摆放顺序是,第一个父类(从左往右)的虚函数表,第二个父类的虚函数表。
fun3的强制转换(father1*)并不是从aClass*到father1*,而执行的是从aClass*到void*再到father1*,所以丢失的信息,从而没有成功。
[解决办法]
引用:

#include "stdafx.h"
#include "stdarg.h"
#include <iostream>

class father1
{
public :
virtual void  fun() 
{
printf("father1\n");;
}
};
class father2
{
public :
virtual void fun2() 
{
printf("father2\n");;
};
};


class aClass:public father2,public father1


{
public:
virtual void fun()
{
printf("aClass\n");
}

};

class bClass:public father1,public father2
{
public:
virtual void fun()
{
printf("aClass\n");
}

};

int fun3(void * test)
{
((father1*)test)->fun();

return 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
aClass at;
bClass bt;

fun3(&at);
fun3(&bt);

system("pause");
}




输出结果:
C++ 多重继承,有没有哦人来说说,该怎么解决   

只有 father1 放在第一个位置 才能实现多态,貌似 在虚函数表里通过偏移来定位函数。  今天被这个坑了一把!


你的问题在于这一句:((father1*)test)->fun();错误地使用了显式转换,在子类到父类的隐式指针转换中,指针指会根据父类子对象的位置发生相应的调整,单继承的情况下,我们通常观察不到这种调整,是由于大多数编译器的类对象模型把子类与父类对象的地址设计为同一的,但在多继承情况下,差别就会出现了,例如对于:

father1* p = &at;

&at的值与p的值是不一样的,因为father1子对象的地址不可能跟aClass对象一样,此时如果p->fun(),就能使用正确的vtbl,但当你显式转换时,(father1*)test的指针值并不会产生相应的调整,从而使test调用了错误的vtbl,实际上,调用错误的vtbl只不过是错误情况之一,由于((father1*)test)->fun();属于未定义行为,它产生任何结果都是可能的,例如崩溃。
[解决办法]
引用:
你的问题在于这一句:((father1*)test)->fun();错误地使用了显式转换,在子类到父类的隐式指针转换中,指针指会根据父类子对象的位置发生相应的调整,单继承的情况下,我们通常观察不到这种调整,是由于大多数编译器的类对象模型把子类与父类对象的地址设计为同一的,但在多继承情况下,差别就会出现了,例如对于:

father1* p = &at;

&at的值与p的值是不一样的,因为father1子对象的地址不可能跟aClass对象一样,此时如果p->fun(),就能使用正确的vtbl,但当你显式转换时,(father1*)test的指针值并不会产生相应的调整,从而使test调用了错误的vtbl,实际上,调用错误的vtbl只不过是错误情况之一,由于((father1*)test)->fun();属于未定义行为,它产生任何结果都是可能的,例如崩溃。

不是显式转换本身的问题。test的类型不是void*而是aClass*或者bClass*的话,static_cast<father1*>依然能够做指针值调整的,即使它是显式转换。

热点排行