C++ 上行对象地址

C++ 上行对象地址,c++,C++,假设B是D的基类(可能是虚拟的,可能是多重继承,不需要是直接基类) 让obj成为D类型的对象(不是D的子类——确切地说是D) 让 我们能安全地假设吗 (char*) d <= (char*) b && (char*) b < (char*) d + sizeof(D) (char*)d如果d是对象的最终类型,我很确定您的假设是安全的。否则,首先使用新的布局将是危险的 #include <stdlib.h> #include <new> st

假设
B
D
的基类(可能是虚拟的,可能是多重继承,不需要是直接基类)

obj
成为
D
类型的对象(不是
D
的子类——确切地说是
D

我们能安全地假设吗

(char*) d <= (char*) b && (char*) b < (char*) d + sizeof(D)

(char*)d如果d是对象的最终类型,我很确定您的假设是安全的。否则,首先使用新的布局将是危险的

#include <stdlib.h>
#include <new>

struct B { int i; };
struct D : virtual B { int j; };

int
main()
{
    auto const storage = malloc(sizeof(D));
    D* d = new (storage) D();
    free(storage);
    return 0;
}
#包括
#包括
结构B{int i;};
结构D:虚拟B{int j;};
int
main()
{
auto const storage=malloc(sizeof(D));
D*D=新(存储)D();
免费(储存);
返回0;
}
如果
B
位于
d
之前,则placement new需要返回一个根据
d
布局调整的指针,但“标准分配函数void*运算符new(std::size\u t,void*)…只返回其第二个参数不变。”()同样,
B
的存储位置不能超出
(char*)d+sizeof(d)
,因为它会超出分配的内存


谢谢分享一个有趣的问题。也许自从提出这个问题以来,你已经找到了一个更令人满意的答案。我有兴趣阅读一个更具体的证据,说明为什么这个假设成立或不成立。

问题是多重继承(例如,C同时继承a和B)。似乎您需要使用
dynamic_cast
,而不是您使用的直接cast。如果您的类继承时没有
多重继承
,则您将始终拥有相同的地址。@pierreemanuellallemant
dynamic\u cast
,即使存在多重继承和虚拟继承,也不需要升级。也就是说,
b=d
并不一定意味着
b
d
是相同的物理地址。我认为答案是肯定的。我意识到这不是一个证明,也有点乏味,但你可以编写一个庞大的测试套件,其中包含大量的
B
D
B2
D2
等组合,以便大致了解。当你说“让
obj
成为
D
类型的对象”时,它必须是最派生的对象吗?它可以是另一个对象的子对象吗?在后一种情况下-是的,虚拟基类的子对象可能物理上位于其派生类的对象之外。在菱形层次结构中,它必须位于至少一个分支上(只有一个虚拟基实例,但从它派生的两个子对象-它们不能同时包含它)。
#include <stdlib.h>
#include <new>

struct B { int i; };
struct D : virtual B { int j; };

int
main()
{
    auto const storage = malloc(sizeof(D));
    D* d = new (storage) D();
    free(storage);
    return 0;
}