好了,它會一點一點技巧。這裏是(簡化)代碼:呼喚的基地之一賦值操作符與C++多重繼承的派生類的虛函數表
class A
{
virtual ~A();
// fields, none of which has an assignment operator or copy constructor
};
class B
{
virtual ~B();
// same as A
};
class Derived : public A, public B
{
Derived();
Derived(const B& b);
// no fields
};
隨着Derived::Derived(const B& b)
(即接受它的一個基地)如下
Derived::Derived(const B& b)
{
*static_cast<B*>(this) = b;
// Do other stuff with protected fields declared in B
}
對我來說,這件事情在「只是避免做這樣」線,但這是一個現有的代碼,我們正在懷疑這個代碼附近有可疑的內存損壞。所以,我很好奇,如果沒關係。
好奇的部分這裏是兩個基類有虛函數表和他們都沒有任何明確的複製/分配構造/運營商。
從我的理解,對於一個Derived
類的內存佈局如下
`Derived`
---------
A-vtable
A-fields
B-vtable
B-fields
,當我調用虛函數,在「B」,宣佈我使用B-vtable
,當我打電話一個虛擬函數,在「A」中聲明,我使用的是A-vtable
,即vtables沒有合併在一起。
而且從我的理解隱含的複製/賦值構造函數/運營商乙方應隻影響B-fields
,當它被稱爲*static_cast<B*>(this) = b;
(static_cast
應該給一個指針開始的B-fields
,與B-vtable
居住在負從中偏移,據我所知) 。
所以,從我的理解,這個代碼是完全安全的,正確的,雖然不清楚,哈克,但安全。我對麼?是否有任何編譯器特定的怪癖我應該知道(我們在這裏討論MSVC 2012)?
編輯:夥計們,我知道複製構造函數/賦值運算符的區別,非常感謝。這是發生在3次複製構造函數中的事件之一,因爲我監督了它,現在每個答案都會花費一半的文本來告訴完全不相關的問題區別。
「經歷了一個微妙的內存損壞可疑接近這個代碼」 - 去提取小例子呢! –
指針如'this'通常指向隱藏字段,其中V表指針被存儲(即,對象的開始,不與偏移到它),因爲它是用來相當頻繁。指針是否來自靜態投射是無關緊要的。我認爲它也可能是負偏移,這可能是一個實現細節。 –