gpt4 book ai didi

c++ - 类层次结构的内存布局

转载 作者:行者123 更新时间:2023-11-30 05:44:25 24 4
gpt4 key购买 nike

我的目标是创建共享一些公共(public)数据的类层次结构的类实例。我创建(使用 union )足够的内存,以便可以在分配的内存中创建最大的实例。现在我想创建/交换类的实例并使用内存中的“旧”数据。这是有效/合法的操作吗?

原始代码使用一些 MTP 内容来创建 union ,目标是使用此类层次结构作为状态机实现的核心。我在这里只显示包含问题的基本代码。

我看到如果基类不包含虚方法但派生类包含虚方法,这是一个问题。这是因为 vtable 指针位于内存前面(在 x86/linux 上使用 gcc)。

一个简单的问题:如果基类的实例是之前创建的,并且派生类的实例重用了内存,那么派生类的实例是否可以访问基类的数据?

class Base
{
public:
int a;
Base()=default;
Base( int _a):a(_a){}

void Print() { cout << "Value: " << a << endl; }
};

class Derived1: public Base
{
public:
int d;

Derived1(): d( 0x11223344){}
};

union U
{
U(){}
Base base;
Derived1 derived1;
} u;

int main()
{
memset( &u, 0, sizeof(u));

new (&u) Base(12345678);
u.base.Print();

new (&u) Derived1;
u.base.Print();
}

最佳答案

不,这行不通,因为标准说:

9.5/1 : in a union, at most one of the non-static data members can be active at any time that is, the value of at most one of the non-static data members can be stored in a union at any time.

你试图做的是未定义的行为:

new (&u) Derived1;  // RISKY !!!

通过放置 new,您可以覆盖之前在 u 中的对象,而不会正确销毁它。然后 Derived1 的创建无论如何都会创建它自己的基础。如果您以某种方式设法将旧值保留在内存中,它仍然是未定义的行为:它可以工作或不工作,具体取决于编译器的对象布局和实现。

关于c++ - 类层次结构的内存布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29865135/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com