c++ - 与兄弟类型之间的侧向转换是否保留 C++ 中的地址?

标签 c++

如果我们编写对 dynamic_cast 的调用并返回到指针值的原始类型,C++ 是否保证保留该值,假设没有 dynamic_cast 失败,即不返回 nullptr?

我查看了 https://www.cprogramming.com/tutorial/virtual_inheritance.html 中的“虚拟继承中的内存布局”部分.这让我对如何实现它有了一个不错的想法。从它的外观来看,似乎不可能获得不同的地址。然而,这只是一个这样的实现,我只是想确保没有符合规范的实现可以返回与原始地址不同的地址。

#include <cassert>

struct A { virtual ~A() {} };
struct B : virtual public A {};
struct C : virtual public A {};
struct D : public B, public C {};

int main()
{
    B* b = new D();
    C* c = dynamic_cast<C*>(b);
    if (c != nullptr)
    {
        B* bp = dynamic_cast<B*>(c);
        assert(bp == b);  // Will this assert ever fire?
    }
    return 0;
}

更一般的情况:

A* a = ...
dynamic_cast<A*>(dynamic_cast<B*>(...(a)...)) is `a` or nullptr

我用 gcc8 和 clang9 运行了上面的代码,它们没有触发断言。

最佳答案

Does side-casting to and from sibling types preserve addresses in C++?

动态转换产生一个指向基础/派生对象的指针,并且该对象只有一个地址。这适用于侧面抛投和向下抛投。

请注意,如果由于具有多个相同类型的非虚拟基而使基不明确,则侧投可能会失败。您的示例没有这种歧义。在这种情况下,将返回 null。

Can any operation change the layout of the object during run-time?

没有。所有对象的布局在创建时就已确定。在标准 C++ 中,所有类型的布局在编译时就已经确定,尽管有语言扩展,例如灵活数组成员,可以放宽这一点。

关于c++ - 与兄弟类型之间的侧向转换是否保留 C++ 中的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58223607/

相关文章:

c++ - c++ 的 gsl_function 替代方案

c++ - 给定方向的 OpenGL 旋转

c++ - 将多维数组的地址复制到指针时的指针维度

c++ - 如何从 TDirect2DCanvas (Direct2D Rendertarget) 复制数据?

c++ - 为什么结构的 sizeof 不等于每个成员的 sizeof 之和?

具有自定义键的 C++ unordered_map 导致空值

c++ - 沿平面剪切后填充网格孔

c++ - GCC -Wshadow 缺少一些案例吗?

javascript - QWebView允许弹窗吗?

c++ - 如何使用 OpenCV Watershed 获取对象之间的轮廓?