2016-02-13 64 views
2

如果有一個類的實例永遠不會被複制並且永遠不會移動,那麼刪除默認的移動和複製構造函數和賦值操作符會有什麼缺點嗎?這確實會直接違背0的規則,但是還有其他什麼缺點(編譯器是否會生成次優代碼,不理想的數據佈局等)?刪除默認C++複製和移動構造函數和賦值運算符的缺點?

+0

實際上是不可能複製/移動課程,或者您是否期望沒有複製/移動? – Pixelchemist

+0

不,它只是輕度討厭處理這些類,但除了他們的行爲像你期望的那樣。 –

+0

如果複製對於所討論的類型沒有意義,則使用'= delete'複製操作。但是,保持移動操作通常是一個好主意。例如,它使您能夠按價值返回它們。與'make_unique'比較 – sp2danny

回答

2

特殊成員函數的存在與否對數據佈局沒有影響。那麼,至少在標準可以保證這一點的程度上。也就是說,一個類是否是標準佈局(因此佈局明確)與構造函數無關。它只與它的成員有關。如果班級不是標準佈局......那麼標準不會保證任何內容。

然而,從理論上講,絕對沒有理由沒有特殊的構造函數來影響類的佈局。

很明顯,標準沒有辦法強制執行「最優代碼」生成。但是,沒有真正的理由說明爲什麼這些成員的存在或缺失會導致爲您定義的函數生成更糟糕的代碼。

聲明一個特殊的成員函數爲刪除應該意味着除了每當有人試圖調用它時導致編譯失敗。

現在,有邊緣案例,但這些圍繞用戶代碼如何使用它們。也就是說,如果您將對這樣的類的引用傳遞給某些想要移動它的模板代碼。但它可以接受不動的類型,但它必須使用較慢的算法來執行此操作(出於某種原因)。它將使用std::is_move_constructible來檢測該類型不可移動並使用較慢的算法。

這不會直接飛到反對0

規則......那又怎樣?規則是使用默認的語義,除非你的類需要其他的語義。 unique_ptr在概念上是一種複製沒有意義的類型,因此它會刪除複製操作。如果你的類型在概念上是複製和移動沒有意義的類型,那麼你應該刪除這些操作。

請注意,「無意義」意味着它在邏輯上無效,這取決於您的類型在做什麼。 A unique_ptr,根據定義,唯一擁有一個對象。複製指針意味着它沒有唯一擁有該對象。由於這在邏輯上是無效的,所以不能複製該類。

如果你的類在概念上是不可移動的,那麼你應該使它在C++中是不可移動的。

0

沒有缺點。但是也沒有優勢。它完全沒有成就。編譯器只在需要時纔會生成默認構造函數或運算符。如果他們不需要,他們是否被正式刪除或沒有任何區別。

現在什麼有所作爲,是當你明確地要強制一個類實例不能被複制,分配等等。有一些原因,爲什麼某些特定的類可能不可分配或移動構建等等。你總是可以定義合適的構造函數或操作符,並引發異常。但是,在這種情況下,您會發現在運行時會出現某些東西。

但是,難道你不認爲它會好得多,而不是編譯時強制執行不移動的構造/賦值/任何操作而不是運行時?因爲如果構造函數/操作符被刪除,並且在某處發生錯誤,編譯器會立即向你大喊。

1

如果一個人有一個類,其實例都不會被複制,從來沒有感動,

這可能意味着兩種情況之一:

  1. 實例絕不被複制或移動,因爲這樣做會導致諸如淺拷貝之類的不好的事情,或者因爲從語義的角度來看它沒有意義。
  2. 實例只是目前沒有發生被複制或移動。

是有什麼缺點刪除默認的移動和複製 構造函數和賦值操作符?

取決於其中兩個含義是正確的:

  1. 號恰恰相反;你應該絕對刪除它們以避免意外調用這些函數。
  2. 是的。當您班級的客戶端代碼發生更改並需要複製或移動時,您將不得不暫時撤消它。或者更糟糕的是,客戶端程序員可能會實施不必要且容易出錯的解決方法,包括指向實例的指針或手動複製:首先從第一個實例中提取數據,然後用提取的數據構建新實例(想象一下,如果std::stringstd::vector不可複製)。
相關問題