C++ 继承语义下构造函数中的对象指针 您所在的位置:网站首页 继承中的构造函数 C++ 继承语义下构造函数中的对象指针

C++ 继承语义下构造函数中的对象指针

2024-07-06 10:12| 来源: 网络整理| 查看: 265

展示一段程序,对其做一些讨论。

1 #include 2 #include 3 using namespace std; 4 5 class X { 6 public: 7 X* ptr; 8 X() { 9 cout 16 (int (*)(...))X::func // slot for the first vfunc /* pseudo code * & : address-of, -> : member access through pointer */ X::X(this): // this is a pointer of type X* this->vptr = (& vtable for X) + 16 // (& this->vptr) : this + 0 print typeinfo::name(& typeinfo for X) // (& this->ptr) : this + 8 this->ptr = this

在构造 y时,先将y的地址作为参数传给Y::Y(), 由 Y::Y() 来对其初始化。 Y::Y() 将y 中 X 子对象的初始化委托给了 X::X(), 最后再在Y::Y() 中对 vptr 赋值。 我这里说"赋值"是因为Y对象的地址与其X子对象的地址相同(这是最简单的情形,子对象地址的偏移值为 0),在X::X()中已经将vptr这个机器字初始化为X的第一个虚函数的在虚表中的位置,在 Y::Y() 中需要覆盖这个不合理的vptr值,将其设置为指向存在于Y的虚表中的第一个虚函数的位置。通过Y对象访问的ptr指针在调用Y::Y()后被初始化为其X子对象的地址,实际上也是Y对象的地址。

下面给出 Y 对象的内存布局、Y 类的虚表 和 Y::Y() 的伪代码:

1 Y object layout Vtable for Y 2 0 vptr ----------+ vtable for Y: 3u entries 3 8 ptr | 0 (int (*)(...))0 4 | 8 (int (*)(...))(& typeinfo for Y) 5 +-------> 16 (int (*)(...))Y::func 6 7 Y::Y(this): // this is a pointer of type Y* 8 X::X(this + 0) 9 this->vptr = (& vtable for Y) + 16 // (& this->vptr) : this + 0

现在很容易知道 x.ptr->func() 和 y.ptr->func() 的输出是什么,这是每个C++程序员都熟悉的动态绑定。 x.ptr 和 y.ptr 均为类型为X*的指针,x.ptr 指向 x,y.ptr 指向y, 但他们调用 func() 时, 通过一致的表达式(在汇编语言中,是一致的命令序列)就可以实现多态, 这得益于基于虚指针和虚表的编译器实现。

体现汇编语言层面语义的伪代码:

// pseudo code // *(ptr) : extract 8 bytes from the address pointed by ptr px = /* x.ptr or y.ptr */ vptr = *(px)    // get the vptr pfunc = *(vptr) // get the function pointer pfunc(px)      // call func()

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有