您的位置:首页 > 编程语言 > C语言/C++

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

2013-05-15 15:37 113 查看
下面的几个问题实际上是准备找工作过程中遇到的,但是一直迟迟没有做出相应的思考。

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

例如,有如下的代码段:

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;
}

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

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

vptr的存储地址是?vptr位于类对象b的内存空间起始处,因此存储vptr的内存地址和&b相同,但是不能说存储vptr的内存地址就是&b。二者类型不同,需要强制类型转换,vptr的存储地址应该是(int*)&b。

虚函数表中存储虚函数地址的地址是?有了vptr的值,我们很快能得到该问题的答案:*(int*)&b。因为vptr指向虚函数表的首地址。

虚函数表中存储首个虚函数的地址是?虚函数的地址在虚函数表中是按照类中声明的顺序存放的,首个虚函数的地址是:*(int*)*(int*)&b,这里也用到了强制类型转换。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: