2015-11-20 23 views
2

對未初始化的數據使用賦值是否危險?使用賦值是危險的,因爲以前的值無效

使用賦值運算符時,何時應該格外小心?

我問的原因是因爲我在看視頻C++ and Beyond 2012: Andrei Alexandrescu - Systematic Error Handling in C++,他在那裏顯示Expected<T>類,它有一個值或一個例外。此舉構造函數定義

Expected(Expected&& rhs) : .. { 
    if (gotHam) new(&ham) T(std::move(rhs.ham)); 
    ... 

其中ham被定義爲

union { 
    T ham; 
    std::exception_ptr spam; 
}; 

他解釋背後使用新的佈局和resoning在28:49,他說,因爲他是用一個結合中,他有要格外小心地管理初始化。他在29:14則進一步指出:

因爲分配假設 前值是有效

我不明白這一點,我不能使用賦值 - 爲什麼會轉讓要求以前的值是有效的?我想這一點,比較的東西:

int i; // unassigned, i.e. not valid 
i = 0; // so this would thus be dangerous? 

我想,也許它已與工會做,而且是未初始化的,但我仍然沒有看到轉讓的危害。爲什麼一項任務會關注以前的價值?

+0

認爲T是一個管理內存的類,但構造函數從未執行過。 –

+0

@RichardHodges好點 - 我的理解是,operator =會創建這些數據,類似於構造函數的操作。但我想運算符=可能會假設這些構造是由前面的構造函數創建的,因此跳過這一步。我在正確的軌道上嗎? :) – Default

+1

聯盟不承擔任何責任。這只是記憶。如何初始化和使用該內存取決於您。這就是爲什麼Andrei的例子有一個標誌 - 告訴周圍代碼哪個成員是有效的。 –

回答

2

他的意思是T的構造函數從來沒有跑過。因此你不能以任何方式使用火腿物體。把它作爲一個這樣的聯合是我知道正式擁有一個可用的命名對象,而不需要構造器正在運行的唯一途徑。

這就是爲什麼我不相信工會在C++程序中有任何地位。

+0

我不明白的是操作符=如何「使用」對象。不是操作符=與構造函數類似,即它將數據分配給對象? – Default

+3

編號Operator =是一個賦值運算符,它使用已經構建的對象。 – SergeyA

+1

@默認情況下,類似於構造函數的運算符是複製構造函數,而不是賦值運算符。 –