虚函数表指针的位置
2009-02-18 14:21
295 查看
XX软件公司的笔试题:
C++标准中,虚表指针在类的内存结构位置没有规定,不同编译器的实现可能是不一样的。请实现一段代码,判断当前编译器把虚表指针放在类的内存结构的最前面还是最后面。
当时的解答是:
#include <iostream>
using namespace std;
typedef unsigned (*Fun)(void);
class Base
{
public:
Base(void){}
virtual unsigned foo(void)
{
cout<<"Construct Base"<<endl;
return 1;
}
public:
virtual ~Base(){}
};
class Derive : public Base
{
public:
Derive(void){}
virtual unsigned foo(void)
{
cout<<"Construct Derive"<<endl;
return 1;
}
};
bool VtlInPre() /*判断虚表指针是否在类结构的前面,是,返回真*/
{
Derive dr;
int** pVtl = (int**)&dr;
Fun pFun = NULL;
pFun = (Fun)pVtl[0][0];
unsigned ret = 0;
ret = pFun();
return (ret == 1) ? true : false;
}
//test
int main()
{
bool tmp = false;
tmp = VtlInPre();
if(tmp)
{
cout<<"the pointer of vitrual table is in HEAD of class"<<endl;
}else
{
cout<<"the pointer of vitrual table is in END of class"<<endl;
}
return 1;
}
一般VC和BCB是将vPtr放在类实例的前四个字节,GCC是放在末尾。在某些情况下需要考虑表指针的位置,比如序列化的时候。
以上的解答用的方法繁琐且不正确,因为,当虚函数表指针是放在类实例末尾的时候,以这种方式来获得的虚表指针就已经不正确了,更何况通过它来调用虚函数。
其实只需将类实例的首地址与类的第一个成员变量地址相比较就可得知虚表指针的位置。
class A
{
A(void){}
virtual void Foo(void){}
};
int main()
{
A a;
char *p1 = reinterpret_cast<char*>(&a);
char *p2 = reinterpret_cast<char*>(&a.n);
if(p1 == p2)
{
cout<<"vPtr is in the end of class instance!"<<endl;
}else
{
cout<<"vPtr is in the head of class instance!"<<endl;
}
return 1;
}
C++标准中,虚表指针在类的内存结构位置没有规定,不同编译器的实现可能是不一样的。请实现一段代码,判断当前编译器把虚表指针放在类的内存结构的最前面还是最后面。
当时的解答是:
#include <iostream>
using namespace std;
typedef unsigned (*Fun)(void);
class Base
{
public:
Base(void){}
virtual unsigned foo(void)
{
cout<<"Construct Base"<<endl;
return 1;
}
public:
virtual ~Base(){}
};
class Derive : public Base
{
public:
Derive(void){}
virtual unsigned foo(void)
{
cout<<"Construct Derive"<<endl;
return 1;
}
};
bool VtlInPre() /*判断虚表指针是否在类结构的前面,是,返回真*/
{
Derive dr;
int** pVtl = (int**)&dr;
Fun pFun = NULL;
pFun = (Fun)pVtl[0][0];
unsigned ret = 0;
ret = pFun();
return (ret == 1) ? true : false;
}
//test
int main()
{
bool tmp = false;
tmp = VtlInPre();
if(tmp)
{
cout<<"the pointer of vitrual table is in HEAD of class"<<endl;
}else
{
cout<<"the pointer of vitrual table is in END of class"<<endl;
}
return 1;
}
一般VC和BCB是将vPtr放在类实例的前四个字节,GCC是放在末尾。在某些情况下需要考虑表指针的位置,比如序列化的时候。
以上的解答用的方法繁琐且不正确,因为,当虚函数表指针是放在类实例末尾的时候,以这种方式来获得的虚表指针就已经不正确了,更何况通过它来调用虚函数。
其实只需将类实例的首地址与类的第一个成员变量地址相比较就可得知虚表指针的位置。
class A
{
A(void){}
virtual void Foo(void){}
};
int main()
{
A a;
char *p1 = reinterpret_cast<char*>(&a);
char *p2 = reinterpret_cast<char*>(&a.n);
if(p1 == p2)
{
cout<<"vPtr is in the end of class instance!"<<endl;
}else
{
cout<<"vPtr is in the head of class instance!"<<endl;
}
return 1;
}
相关文章推荐
- [C++ MFC VC] 虚函数表指针的位置
- 虚函数表指针位置
- C++指向虚函数表指针存放位置
- 虚函数表位置思考
- 有n个整数,使前面各数顺序向后移m个位置,最后m个数变成最前面m个数。(指针)
- 虚函数表在内存中的位置
- 混迹于C++之虚函数表指针,虚函数表
- php中将指针移动到数据集初始位置的实现代码[mysql_data_seek]
- 文件输入输出函数fgetc/fputc及fgets/fputs等文件指针位置的变化
- c语言中,指针*位置应该放哪里?
- vtbl(虚函数表)与vptr(虚函数表指针)
- 【转】vtbl(虚函数表)与vptr(虚函数表指针)
- jQuery实时显示鼠标指针位置和键盘ASCII码
- jQuery实时显示鼠标指针位置和键盘ASCII码
- 文件的操作2-----读写文件/移动文件读写指针位置/重回文件头部、fprintf()函数、freopen函数
- 设某循环队列的容量为50,如果头指针front=45(指向队头元素的前一位置),尾指针rear=10(指向队尾元素),则该循环队列中共有元素个数为?
- 鼠标指针位置坐标
- 虚函数表指针和虚继承
- 数据结构之头指针链表的逆序、输出和指定位置的删除
- 单一继承下无虚函数覆盖__虚函数表中的虚函数指针的获取