複製構造函數傳統上在C++程序中無處不在。不過,我懷疑自從C++ 11以來是否有充分的理由。我們可以說再見覆制構造函數嗎?
即使在程序邏輯並不需要複製對象,拷貝構造函數(通常爲默認值。)往往包括了對象再分配的唯一目的。如果沒有複製構造函數,則無法將對象存儲在std::vector
中,甚至不能從函數返回對象。
但是,自從C++ 11以來,移動構造函數一直負責對象的重新分配。
複製構造函數的另一個用例是簡單地創建對象的克隆。不過,我很相信,一個.copy()
或.clone()
方法更適合這個角色不是一個拷貝構造函數,因爲...
複製對象是不是真的司空見慣。當然有時候對象的接口有時需要包含一個「自己創建一個副本」的方法,但有時候只是這樣。當情況是這樣的時候,顯式比隱式更好。
有時對象可能會暴露幾種不同的
.copy()
類似的方法,因爲在不同的上下文中,可能需要以不同的方式創建副本(例如,更淺或更深)。在某些情況下,我們希望
.copy()
方法可以做與程序邏輯有關的非平凡事情(增加一些計數器,或者爲副本生成一個新的唯一名稱)。我不會接受任何複製構造函數中具有非顯而易見的邏輯的代碼。最後但並非最不重要的一個
.copy()
方法可以是虛擬的,如果需要,允許解決slicing的問題。
那裏其實我想用一個拷貝構造函數的唯一情況是:
- 可複製資源的RAII手柄(很明顯)
- 結構,其意在像內置類型一樣使用,如數學向量或矩陣 -
僅僅是因爲它們經常被複制,並且vec3 b = a.copy()
太冗長。
附註:我認爲複製是需要CAS構造的事實,但需要
operator=(const T&)
我認爲確切的同樣的理由冗餘築底CAS;如果你真的需要這個
.copy()
+operator=(T&&) = default
將是首選。)
對於我來說,這是相當足夠的激勵默認使用T(const T&) = delete
無處不在,在需要的時候提供一個.copy()
方法。 (也許還有一個private T(const T&) = default
只是爲了能夠寫copy()
或virtual copy()
沒有樣板。)
問:上述推理是否正確,或者我錯過了爲什麼邏輯對象實際需要或以某種方式從複製構造函數中受益的任何好理由?
具體來說,我正確的移動構造函數完全接管了C++ 11中對象重新分配的責任嗎?當一個對象需要在內存中的其他位置移動而不改變其狀態時,我正在非正式地使用「重新分配」。
「複製對象並不是很平常。」 - 我認爲考慮到C++默認使用值語義是很常見的。具有相同值的兩個對象應表示相同的事物。 – 2013-05-08 19:04:46
默認禁用複製可能有一定的優點;但爲什麼你會通過成員函數啓用它,而不是複製構造函數的慣用使用呢? – 2013-05-08 19:09:18
@sftrabbit:不一定:值不是多態的,引用和指針是。如果你想在C++中使用運行時多態性,你可以通過地址來標識對象,而不是值(它只表示「狀態」,而不是「標識」)。兩個具有相同'm_name'的'Person's不是相同的'Person'。 – 2013-05-09 06:28:34