VPTR与构造函数和继承

原创 2007年09月11日 20:03:00
    C++中类的成员函数默认情况下是non-virtual,即被调用时为静态绑定。
   
   
至少包含一个virtual成员函数的类,都有一个VTABLE——虚函数映射表,表中的每项对应类中一个virtual成员函数的函数体地址。相应的该类的每个对象在为其分配存储空间时,编译器会额外的为每个对象附加一个指针VPTR,该指针指向该对象所属类的VTABLE。

    一定要明确概念,VTABLE是在类这个层次上的概念,而VPTR则是在对象这个层次上的概念。

    将VPTR正确设置、指向合适的VTABLE,这是由谁负责完成的?类的构造函数。编译器会自动的在构造函数中插入设置VPTR的代码。

    常见的实现中,编译器会将VPTR放在对象所占空间的头部。

    对于单重继承关系中的子类对象,其VPTR的设置则经历如下两个阶段

    A).首先,在基类构造函数中,VPTR被设置为指向基类的VTABLE
    B).之后,在子类构造函数中,VPTR被设置为指向子类的VTABLE

    注意,这里只存在一个VPTR,在子对象的构建过程中被重写。

    而对于多重继承,有类似的过程,不过子类对象中存在不止一个VPTR。

下面是一个简单的验证代码,可以观察VPTR是如何被重写,以及指向何处

#include <iostream>

using namespace std;

class Base
...{
public:
    
int x;
    Base():x(
0)
    
...{
    
void * pv=this;
    
int *  pi=static_cast<int *>(pv);
    printf(
"vptr in base ctor point to : %x ",*pi);

    }

    
virtual ~Base()...{}
}
;

class Derived:public Base
...{
public:
    Derived()
    
...{

    
void * pv=this;
    
int *  pi=static_cast<int *>(pv);
    printf(
"vptr in derived  point to : %x ",*pi);
    }


}
;


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

    Base Ba;
    Derived Da;

    
void * pv=&Ba;
    
int * pi=static_cast<int *>(pv);
    printf(
"address of Base's vTable  : %x ",(*pi));


    pv
=&Da;
    pi
=static_cast<int *>(pv);
    printf(
"address of Derived's vTable  : %x ",(*pi));

    
return 1;
}


运行结果

vptr in base ctor point to :    8048af0

vptr 
in base ctor point to :    8048af0     //initialized by base ctor
vptr in derived  point to :     8048b10     //overwritten by derived ctor 

address of Base
's vTable  :     8048af0
address of Derived's vTable  :  8048b10

VPTR和VTABLE和构造函数与继承

C++中类的成员函数默认情况下是non-virtual,即被调用时为静态绑定。          至少包含一个virtual成员函数的类,都有一个VTABLE——虚函数映射表,表中的每项对应类中一...
  • xiatianhappy
  • xiatianhappy
  • 2016年04月17日 20:01
  • 531

C++中vptr指针的存在

在实现多态的时候三个步骤: (1)必须有继承 (2)必须有virtual关键字 (3)有父类指针指向子类对象 其实在实现多态的时候,申明为虚函数是,编译器会自动生成一个虚函数表 当存在虚函数...
  • sum_TW
  • sum_TW
  • 2016年10月30日 23:54
  • 1892

C++继承中构造函数、析构函数调用顺序及虚析构函数

C++继承中构造函数、析构函数调用顺序及虚析构函数 首先说说构造函数,大家都知道构造函数里就可以调用成员变量,而继承中子类是把基类的成员变成自己的成员,那么也就是说子类在构造函数...
  • u012861978
  • u012861978
  • 2016年02月16日 11:29
  • 1088

虚函数表(vtbl)和虚表指针(vptr)

上一篇文还留了个问题没解决呢:就是关于那个虚函数指针的问题。其实这样称呼这个指针是不正确的,他确切的应该称为“虚表指针”。不废话了直接进入正题吧。当类中有虚函数的时候,编译器会为类插入一个我们看不见的...
  • lishengwei
  • lishengwei
  • 2008年05月08日 15:42
  • 6956

C++11中继承构造函数和委派构造函数

1、继承构造函数 在C++继承中,我们可能会遇到下面这个例子 class Base { public: Base(int va) :m_value(va) { } Base(ch...
  • yp18792574062
  • yp18792574062
  • 2017年07月08日 22:34
  • 287

C++ 多重继承和虚拟继承的内存布局(vtable,vptr)

Reproduced address:http://www.phpcompiler.org/articles/virtualinheritance.html Memory Layout for Mul...
  • u013617648
  • u013617648
  • 2015年06月21日 15:55
  • 873

python学习笔记——旧类与新类继承中的构造函数

旧类以调用未绑定的超类构造方法 class OldDog: def __init__(self): print 'I am a old dog !' sel...
  • XiaoPANGXia
  • XiaoPANGXia
  • 2015年07月18日 15:20
  • 2955

转载::VPTR与构造函数和继承 ; 虚函数与内联

C++中类的成员函数默认情况下是non-virtual,即被调用时为静态绑定。        至少包含一个virtual成员函数的类,都有一个VTABLE——虚函数映射表,表中的每项对应类中一个vir...
  • lgxqf
  • lgxqf
  • 2007年11月11日 22:24
  • 664

C++ 构造函数和析构函数是否可以继承?

先看一个例子: #include class A { public: A() { ::std::cout
  • duyiwuer2009
  • duyiwuer2009
  • 2014年11月12日 18:13
  • 5280

继承中构造函数和析构函数的调用次序

1.构造函数 构造函数的调用次序(创建派生类对象时): 首先调用其基类的构造函数(调用顺序按照基类被继承时的声明顺序(从左向右))。 然后调用本类对象成员的构造函数(调用顺序按照对象成员在类中的...
  • snake29
  • snake29
  • 2016年04月29日 14:12
  • 264
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VPTR与构造函数和继承
举报原因:
原因补充:

(最多只允许输入30个字)