大佬教程收集整理的这篇文章主要介绍了c – 当基类不是多态的但是派生的时候,这个地址不匹配,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
#include <iostream> class Base { public: Base() { std::cout << "Base: " << this << std::endl; } int x; int y; int z; }; class Derived : Base { public: Derived() { std::cout << "Derived: " << this << std::endl; } void fun(){} }; int main() { Derived d; return 0; }
输出:
Base: 0xbfdb81d4 Derived: 0xbfdb81d4
但是当派生类中的功能“fun”更改为虚拟时:
virtual void fun(){} // changed in Derived
Base: 0xbf93d6a4 Derived: 0xbf93d6a0
另一件事是如果类Base是多态的,例如我添加了一些其他的虚函数:
virtual void funOther(){} // added to Base
然后再次地址“this”匹配:
Base: 0xbfcceda0 Derived: 0xbfcceda0
问题是 – 为什么在Base类和Derived类不同时,Base类和Derived类中的’this’地址是不同的?
但是,当层次结构中的基类不是多态时,它不会引入VMT指针. VMT指针将由层次结构中较低层的第一个多态类引入.在这种情况下,普遍的@L_489_13@是在由层次结构的非多态(上)部分引入的数据之前插入VMT指针.这是你在第二个实验中看到的. Derived的内存布局如下所示
+------------------------------------+ <---- `this` value for `Derived` and below | VMT pointer introduced by Derived | +------------------------------------+ <---- `this` value for `Base` and above | Base data | +------------------------------------+ | Derived data | +------------------------------------+
同时,层次结构的非多态(上)部分中的所有类都不应该知道任何VMT指针. Base类型的对象必须以数据字段Base :: x开头.同时层次结构的多态(下)部分中的所有类必须以VMT指针开头.为了满足这两个要求,编译器被强制调整对象指针值,因为它将层次结构从一个嵌套的子对象转换为另一个.这意味着跨多态/非多态边界的指针转换不再是概念性的:编译器必须添加或减少一些偏移量.
来自层次结构的非多态部分的子对象将共享它们的值,而来自层次结构的多态部分的子对象将共享它们自己的不同的该值.
在沿着层次结构转换指针值时不得不添加或减少一些偏移量是不寻常的:编译器必须在处理多重继承层次结构时一直执行此操作.但是,您的示例显示了如何在单继承层次结构中实现它.
Derived *pd = new Derived; Base *pb = pd; // Numerical values of `pb` and `pd` are different if `Base` is non-polymorphic // and `Derived` is polymorphic Derived *pd2 = static_cast<Derived *>(pb); // Numerical values of `pd` and `pd2` are the same
以上是大佬教程为你收集整理的c – 当基类不是多态的但是派生的时候,这个地址不匹配全部内容,希望文章能够帮你解决c – 当基类不是多态的但是派生的时候,这个地址不匹配所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。