我的目標是創建共享某些常用數據的類層次結構類的實例。我創建了(有聯合)足夠的內存,以便可以在分配的內存中創建最大的實例。現在我想創建/交換類的實例,並在那裏的內存中使用「舊」數據。這是有效/合法的操作嗎?類層次結構的內存佈局
原始代碼使用一些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