[英]c++ Multiple Inheritance - Compiler modifying my pointers
如果我運行以下代碼,我會打印不同的地址。 為什么?
class Base1 {
int x;
};
class Base2 {
int y;
};
class Derived : public Base1, public Base2 {
};
union U {
Base2* b;
Derived* d;
U(Base2* b2) : b(b) {}
};
int main()
{
Derived* d = new Derived;
cout << d << "\n";
cout << U(d).d << "\n";
return 0;
}
更有趣的是,如果你反復進出聯盟,地址會繼續增加4,就像這樣
int main()
{
Derived* d = new Derived;
cout << d << "\n";
d = U(d).d;
cout << d << "\n";
d = U(d).d;
cout << d << "\n";
return 0;
}
如果聯合被修改為這樣,那么問題就會消失
union U {
void* v;
Base2* b;
Derived* d;
U(void* v) : v(v) {}
};
此外,如果任一基類都為空,則問題就會消失。 這是編譯器錯誤嗎? 我希望它能讓我的指針獨自一人。
如果我運行以下代碼,我會打印不同的地址。 為什么?
因為Base2
中的子對象Derived
的對象是不是在開始Derived
對象。 所以地址不同。 當編譯器執行從Derived*
到Base2*
的隱式轉換時,它需要調整地址。
給定Base1
和Base2
類的定義, Derived
類的兩個子對象都不可能位於Derived
對象的起始地址 - 兩個子對象的該地址都沒有空間。
說你有這個代碼:
Derived* d = new Derived;
Base1* pb1 = d;
Base2* pb2 = d;
它怎么會是可能的pb1
和pb2
指向同一個地址? pb1
必須指向一個Base1::x
項,而pb2
必須指向一個Base2::y
項(並且這些項必須是不同的)。
更有趣的是,如果你反復進出聯盟,地址會繼續遞增4
因為你在寫入b
成員后從union的d
成員讀取,這是未定義的行為(你實際上在Base2*
上執行類似reinterpret_cast<Derived*>()
操作)。
我希望它能讓我的指針獨自一人。
如果你想要一個Base2*
指針,那就沒有了。 多重繼承使事情變得更加復雜 - 這就是為什么許多人建議避免它,除非絕對必要。
union構造函數從不初始化成員d
union構造函數有一個bug,它不是用參數b2初始化成員b,而是用自己初始化b
// b(b) should probably be b(b2)
U(Base2* b2) : b(b) {}
當您的第一個主函數示例嘗試構造U的實例,並且打印成員d時,它實際上是打印未定義的值,因為成員d尚未初始化,並且不保證可以訪問。
// U(d) doesn't construct member d, so .d returns an undefined value
cout << U(d).d << "\n";
關於你的第二個主要功能例子
// d is set to a newly constructed instance of Derived
Derived* d = new Derived;
// current address of d is printed
cout << d << "\n";
// a new instance of U is constructed. The address of member d will be in close
// proximity to the newly initialized U instance, and is what will be printed
d = U(d).d;
cout << d << "\n";
// yet another new instance of U is constructed, and again, the address of member
// d will be in close proximity to the newly initialized U instance, and is
//what will be printed
d = U(d).d;
cout << d << "\n";
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.