我的目标是创建共享某些常用数据的类层次结构类的实例。我创建了(有联合)足够的内存,以便可以在分配的内存中创建最大的实例。现在我想创建/交换类的实例,并在那里的内存中使用“旧”数据。这是有效/合法的操作吗?类层次结构的内存布局
原始代码使用一些MTP东西来创建联合,目标是使用这个类层次作为状态机实现的核心。我只在这里显示包含问题的基本代码。
我看到,如果基类不包含虚拟方法,但派生的方法确实存在问题,那么这是一个问题。这是因为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();
}
做OOP时这是完全错误的做法。你应该使用'Base *'指针,它可以指向任何派生类。 – Barmar
问题不在于如何通过指针访问数据。问题在于层次结构中的布局是否安全以便在层次结构中使用公共数据是安全的。原始代码应该使用派生类中的数据。所提供的代码仅用于查看效果。 – Klaus