2016-10-21 58 views
0

我一直在閱讀C++ 11的新移動語義,以及我不清楚的是,如果使用自定義構造函數會阻止編譯器自動將移動語義添加到您的類中。我不明白5的規則是否也包括如下的簡單類。實現構造函數是否阻止自動移動語義?

我有下面的類:

class CodeFile 
{ 
private: 
    std::vector<Function> functions; 
    //std::vector<std::wstring, unsigned long> variables; 
    std::vector<std::wstring> lines; 
    std::vector<unsigned char> constants; 

public: 
    std::wstring directory; 
    std::wstring fileName; 

    void setFilePath(std::wstring filePath); 
    bool addFunction(Function function); 
    void Run(); 
    void Finalize(); 

    CodeFile(std::wstring filePath); 
}; 

隨着最後一行是構造函數。定義這個構造函數是否會阻止編譯器通過添加移動構造函數來優化類?

我應該聲明類如下嗎?

class CodeFile 
{ 
private: 
    std::vector<Function> functions; 
    //std::vector<std::wstring, unsigned long> variables; 
    std::vector<std::wstring> lines; 
    std::vector<unsigned char> constants; 

public: 
    std::wstring directory; 
    std::wstring fileName; 

    void setFilePath(std::wstring filePath); 
    bool addFunction(Function function); 
    void Run(); 
    void Finalize(); 
    static CodeFile fromFile(std::wstring filePath); 
}; 
+1

是。提供自己的構造函數將會抑制自動生成的構造函數的生成。 –

+3

@πάνταῥεῖ編號用戶定義的構造函數不會停止生成移動構造函數 – NathanOliver

回答

2

你沒有必要在這裏做任何事情。 C++會爲你寫你的移動構造函數。

然而,當你擔心這一點,只需添加

CodeFile(CodeFile &&)=default; 
CodeFile(CodeFile const&)=default; 
CodeFile& operator=(CodeFile &&)=default; 
CodeFile& operator=(CodeFile const&)=default; 

,並可能

CodeFile()=default; 

這是一個有點討厭的樣板式的,但它也是無害的,並表示要在類是可複製和可移動的(或者你是瘋狂的通用代碼,並希望它的複製/可移動性依賴於它的父母和內容)。

請注意,除非是真正的轉換,否則不應該有非顯式的單參數構造器。所以考慮explicitCodeFile(std::wstring)

但是,禁用CodeFile(CodeFile&&)自動寫入的任何操作也會禁止自動寫入CodeFile(CodeFile const&)。所以如果你發現你不能複製它,你也可以不再移動它(除非你手動地寫了CodeFile(CodeFile const&),這當然會禁用CodeFile(CodeFile&&)而不禁用它自己。)。

要診斷這樣的事情,我平時寫noisy

struct noisy { 
    noisy(){std::cout << "ctor()\n";} 
    noisy(noisy&&){std::cout << "ctor(&&)\n";} 
    noisy(noisy const&){std::cout << "ctor(c&)\n";} 
    void operator=(noisy&&){std::cout << "asgn(&&)\n";} 
    void operator=(noisy const&){std::cout << "asgn(c&)\n";} 
    ~noisy() {std::cout << "~\n"; } 
}; 

這不只是製造噪音。

我們再編寫一個玩具類型:

struct Foo { 
    Foo (int) {} 
    noisy _; 
}; 

與我們關心的屬性。

一個測試的一點:

Foo f(7); 
f = Foo(3); 
Foo f2=std::move(f); 

證明,此舉構造的罰款。我們編寫的Foo(int)只有從Foo中刪除了默認的構造函數。

live example

+0

那麼爲什麼用戶定義的構造函數會阻止[隱式聲明的移動構造函數](http://en.cppreference.com/w/cpp/language/ move_constructor#隱式declared_move_constructor)? – songyuanyao

1

我應該如下聲明這個類嗎? ...

號就宣佈你需要自動生成的構造函數如下

CodeFile(CodeFile&&) = default; 
相關問題