虚函数表指针的位置

   XX软件公司的笔试题:

  C++标准中,虚表指针在类的内存结构位置没有规定,不同编译器的实现可能是不一样的。请实现一段代码,判断当前编译器把虚表指针放在类的内存结构的最前面还是最后面。

  当时的解答是:

#include
using namespace std;

typedef unsigned (*Fun)(void);

 

class Base
{
public:
    Base(void){}
    virtual unsigned foo(void)
    {
         cout<<"Construct Base"<         return 1;
    }

public:

    virtual ~Base(){}
};

 

class Derive : public Base
{
public:
    Derive(void){}
    virtual unsigned foo(void)
    {
         cout<<"Construct Derive"<         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"<    }else
    {
        cout<<"the pointer of vitrual table is in END of class"<    }
    return 1;

  一般VC和BCB是将vPtr放在类实例的前四个字节,GCC是放在末尾。在某些情况下需要考虑表指针的位置,比如序列化的时候。

  以上的解答用的方法繁琐且不正确,因为,当虚函数表指针是放在类实例末尾的时候,以这种方式来获得的虚表指针就已经不正确了,更何况通过它来调用虚函数。

  其实只需将类实例的首地址与类的第一个成员变量地址相比较就可得知虚表指针的位置。

class A
{
      A(void){}
      virtual void Foo(void){}
};

 

int main()
{
     A a;
     char *p1 = reinterpret_cast(&a);
     char *p2 = reinterpret_cast(&a.n);
     if(p1 == p2)
     {
        cout<<"vPtr is in the end of class instance!"<     }else
     {
        cout<<"vPtr is in the head of class instance!"<     }
     return 1;

你可能感兴趣的:(C++/STL)