2016-10-21 4 views
0

Ich habe in der neuen Move-Semantik von C++ 11 nachgelesen, und was mir nicht klar ist, ist, wenn ein benutzerdefinierter Konstruktor verhindert, dass der Compiler automatisch Bewegungssemantik zu Ihrer Klasse hinzufügt. Ich verstehe nicht, ob die Regel von 5 auch einfache Klassen wie die folgende enthält.verhindert die Implementierung eines Konstruktors die automatische Umzugsemantik?

Ich habe die folgende Klasse:

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); 
}; 

Mit der letzten Zeile der Konstruktor ist. Erlaubt die Definition dieses Konstruktors, dass der Compiler die Klasse nicht durch Hinzufügen von Move-Konstruktoren optimiert?

Soll ich die Klasse stattdessen wie folgt deklarieren?

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

Ja. Die Bereitstellung eines eigenen Konstruktors unterdrückt die Generierung der automatisch generierten Konstruktoren. –

+3

@ πάνταῥεῖ Nein. Ein benutzerdefinierter Konstruktor verhindert nicht, dass ein Verschiebungskonstruktor generiert wird. – NathanOliver

Antwort

2

Sie müssen hier nichts tun. C++ schreibt Ihren Move-Konstruktor für Sie.

Jedes Mal, wenn Sie sich Sorgen darüber sind, fügen Sie einfach

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

und möglicherweise

CodeFile()=default; 

Dies ist ein bisschen ärgerlich vorformulierten, aber es ist auch harmlos und drückt aus, dass Sie das wollen Klasse, um kopierbar und beweglich zu sein (oder Sie sind in wahnsinnig generischem Code und wollen, dass seine Kopie/Beweglichkeit von ihren Eltern und Inhalt abhängt).

Hinweis: Sie sollten keinen nicht expliziten Konstruktor mit einem Argument haben, es sei denn, es handelt sich um eine echte Konvertierung. So betrachten explicit auf CodeFile(std::wstring).

Jedoch deaktiviert alles, was das automatische Schreiben von CodeFile(CodeFile&&) deaktiviert, auch das automatische Schreiben von CodeFile(CodeFile const&). Wenn Sie also feststellen, dass Sie es nicht mehr kopieren können, können Sie es auch nicht mehr verschieben (es sei denn, Sie haben manuell CodeFile(CodeFile const&) geschrieben, wodurch CodeFile(CodeFile&&) deaktiviert wird, ohne sich selbst zu deaktivieren.).

Um Dinge wie diese Diagnose, ich noisy in der Regel schreiben:

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"; } 
}; 

, die nichts tut, aber Lärm machen.

Wir haben dann ein Spielzeug Art schreiben:

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

mit den Eigenschaften wir kümmern uns um.

Ein wenig Test:

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

zeigt, dass die Bewegung Konstrukteure sind in Ordnung. Nur der Standardkonstruktor wurde von Foo durch unser Schreiben von Foo(int) entfernt.

live example.

+0

Also warum benutzerdefinierte ctor verhindern [implizit deklarierter Verschiebekonstruktor] (http://en.cppreference.com/w/cpp/language/ move_constructor # Implizit-deklarierter_Move_Konstruktor)? – songyuanyao

1

Soll ich die Klasse stattdessen wie folgt deklarieren? ...

Nr erklären Sie die Konstrukteure automatisch generiert müssen wie folgt

CodeFile(CodeFile&&) = default; 
Verwandte Themen