2016-03-02 76 views
0

我想創建一個基類,它既有非拷貝也有不可移動。不可複製和不可移動?

class noncopyable { 
protected: 
    noncopyable() = default; 
    ~noncopyable() = default; 

    noncopyable(noncopyable const &) = delete; 
    noncopyable &operator=(noncopyable const &) = delete; 
}; 

class nonmovable { 
protected: 
    nonmovable() = default; 
    ~nonmovable() = default; 

    nonmovable(nonmovable &&) = delete; 
    nonmovable &operator=(nonmovable &&) = delete; 
}; 

是否有任何情況下,類應該是非複製和不可移動?

class non : public noncopyable, public nonmovable { 
}; 

class foo : public non { 
}; 

如果有,那麼「非」類的方便名稱應該在這裏?

+4

「那是方便嗎?」不是真的。 – CoffeeandCode

+2

當然,它可能非常有用。但是你也可以使用'boost :: noncopyable'。通常你不需要公有繼承。被刪除的東西可以是「私人」的。 – juanchopanza

+6

你的'nonmovable'和你的'noncopyable'完全一樣。它應該是什麼樣子? – Angew

回答

3

雖然「不可複製」將工作中,「不可移動的」基類不會提供你所期望的:

#include <utility> 
#include <iostream> 

struct nonmovable 
{ 
    nonmovable() = default; 
    nonmovable(const nonmovable&) { std::cout << "copy\n"; } 
    nonmovable& operator = (const nonmovable&) { std::cout << "asign\n"; return *this; } 
    nonmovable(nonmovable&&) = delete; 
    nonmovable& operator = (nonmovable&&) = delete; 
}; 

struct X : nonmovable {}; 

int main() 
{ 
    nonmovable n0; 
    nonmovable n1(n0); 
    // error: use of deleted function ‘nonmovable::nonmovable(nonmovable&&)’: 
    //nonmovable n2(std::move(n0)); 

    X x0; 
    X x1(x0); 
    // However, X has a copy constructor not applying a move. 
    X x2(std::move(x0)); 
} 

此外,移動建築和移動分配必須明確的拷貝構造函數刪除後啓用,如果需要的話:

struct noncopyable 
{ 
    noncopyable() = default; 
    // Deletion of copy constructor and copy assignment makes the class 
    // non-movable, too. 
    noncopyable(const noncopyable&) = delete; 
    noncopyable& operator = (const noncopyable&) = delete; 

    // Move construction and move assignment must be enabled explicitly, if desiered. 
    noncopyable(noncopyable&&) = default; 
    noncopyable& operator = (noncopyable&&) = default; 
}; 

這個名字「noncopyable」和「nonmovable」本身就是很好的描述性名字。然而,「boost :: noncopyable」既是(不可複製的也是不可移動的),這可能是一個更好的(歷史)設計決策。

+0

確實「X x2(std :: move(x0));」調用移動構造函數或複製構造函數。如果複製構造函數被調用。我達到了我的目標。 – mustafagonul

+0

@mustafagonul X的拷貝構造函數(X沒有移動構造函數,無論如何) –

-2

作爲一個例子 - signleton模式。另外,如果你定義了copy-constructor/assignment operator/destructor,那麼move-constructor/assignment不會被生成。

+0

不是真的。看看標準C++ –

+0

中的互斥類以及?互斥量可以通過標準移動。這取決於供應商,如何實施它。 – jonezq

+2

@jonezq [不同意](http://www.cplusplus.com/reference/mutex/mutex/mutex/)。一個'std :: mutex'不能被標準移動。 – nwp

3

有人認爲,例如here,​​表明​​首先是一個壞主意。

有四個合理的方案:

  1. 類型自然是可複製和可移動的。
  2. 類型不可複製,但可移動。
    這種情況經常發生在管理資源時,並且複製資源是不可能的,或者如此昂貴以至於不可取。
  3. 類型沒有特殊的可移動性 - 移動ctor只需調用copy ctor。
    如果由於技術原因,您不想爲這種類型的對象創建「空狀態」,或者沒有便宜/自然的方式將移動的對象置於任何可接受的狀態。
  4. 類型既不可複製也不可移動。
    這可能發生在一個靜態單例或類似的東西,移動或複製它是不應該發生在你的程序中,你想防止發生編譯時錯誤。

如果該類型是可複製的,但移動它失敗,這是一個嚴格的安排,而應移動到備份複製。當拷貝沒問題時,移動失敗沒有任何優勢,它只會抑制泛型編程。

所以,也許你應該只有「不可複製」和「非」,但不是「不可移動」?

相關問題