C++中的虚函数分析(1)

下面的几个问题实际上是准备找工作过程中遇到的,但是一直迟迟没有做出相应的思考。

一.首先这里要提出一个问题,怎样才能获取虚函数表指针的存储地址虚函数表指针的值虚函数表的存储地址以及虚函数表中存储的虚函数地址

例如,有如下的代码段:

class  Base {

  public:

    virtual int fun1() {

      std::cout << "Base::fun1()" << std::endl;
    }

    virtual int fun2() {

      std::cout << "Base::fun2()" << std::endl;
    }

    virtual int fun3() {

      std::cout << "Base::fun3()" << std::endl;
    }

  private:
};

int main(int argc, char* argv[]) {

  Base  b;

  //获取类对象b的地址,实际上也是虚函数表指针vptr的地址,

  //因为vptr位于对象b的起始位置。

  std::cout << &b << std::endl;

  //但是怎样获取vptr的内容?vptr为指针类型,4bytes。

  std::cout << *(int*)&b << std::endl;

  //获取vptr的内容,相当于获取虚函数表的首地址。

  //怎样获取虚函数表中第一个函数的地址?

  //即是虚函数int fun1()的地址。

  std::cout << *(int*)*(int*)&b << std::endl;

  //那么虚函数int fun2()的地址也就得到。

  std::cout << *((int*)*(int*)&b + 1)  << std::endl;

 

  return 0;
}

 

虽然在上述代码中给出了所提问题的答案,但是要问自己几个问题?除了对于虚函数的

基本理解外,实质是关于指针的问题。

  1. vptr的存储地址是?vptr位于类对象b的内存空间起始处,因此存储vptr的内存地址和&b相同,但是不能说存储vptr的内存地址就是&b。二者类型不同,需要强制类型转换,vptr的存储地址应该是(int*)&b。
  2. 虚函数表中存储虚函数地址的地址是?有了vptr的值,我们很快能得到该问题的答案:*(int*)&b。因为vptr指向虚函数表的首地址。
  3. 虚函数表中存储首个虚函数的地址是?虚函数的地址在虚函数表中是按照类中声明的顺序存放的,首个虚函数的地址是:*(int*)*(int*)&b,这里也用到了强制类型转换。

 

posted on 2013-05-15 15:37  Persistence  阅读(190)  评论(0编辑  收藏  举报

导航