2017-09-11 2 views
1

ich den folgenden Code haben:Warum wird der Kopierkonstruktor hier aufgerufen?

template<class T = char> 
class String 
{ 
public: 

    // Default constructor 
    String() 
     : buffer(nullptr), 
     len(0) 
    { 
     cout << "Default constructor" << endl; 
    } 

    // Constructor 
    String(const char* s) 
    { 
     cout << "Constructor (const char*)" << endl; 
     //... 
    } 

    // Virtual destructor. 
    virtual ~String() 
    { 
     cout << "Destructor" << endl; 
     len = 0; 
     delete[] buffer; 
    } 


    // Copy constructor 
    String(const String& s) 
    { 
     cout << "Copy constructor" << endl; 
     buffer = new T[s.len]; 
     std::copy(s.buffer, s.buffer + s.len, buffer); 
     len = s.len; 
    } 


    // Copy assignment operator (uses copy and swap idiom) 
    String& operator=(String s) 
    { 
     cout << "Copy assignment operator (copy and swap idiom)" << endl; 
     std::swap(buffer, s.buffer); 
     return *this; 
    } 


    // Move constructor 
    String(String&& s) 
    { 
     cout << "Move constructor" << endl; 
    } 


    // compound assignment (does not need to be a member, 
    // but often is, to modify the private members) 
    String& operator+=(const String& rhs)        
    {       
     cout << "operator+=" << endl;  
     //... 

     return *this; // return the result by reference 
    } 

    // friends defined inside class body are inline and are hidden from non-ADL lookup 
    // passing lhs by value helps optimize chained a + b + c 
    // otherwise, both parameters may be const references 
    friend String operator+(String lhs, const String& rhs) 
    { 
     cout << "operator+" << endl; 

     lhs += rhs; // reuse compound assignment 
     return lhs; // return the result by value (uses move constructor) 
    } 


private: 

    T* buffer; 
    size_t len; 

}; 


int main() 
{ 
    String<> s("Hello "); 
    String<> s2("World"); 

    // call copy constructor first? 
    String<> s3 = s + s2; 

    return 0; 
} 

und der Ausgang ist:

Constructor (const char*) 
Constructor (const char*) 
Copy constructor 
operator+ 
operator+= 
Move constructor 
Destructor 

ist meine Frage, warum der Copykonstruktor wird sofort gerufen:

String<> s3 = s + s2; 
+0

2. Fragen Sie, warum eine Kopie nicht gelöscht wird? – juanchopanza

+0

@juanchopanza Der Rückgabewert (der ein R-Wert ist) wird tatsächlich verschoben. – Nick

+0

@juanchopanza - lhs wird aus der Funktion und in den Rückgabewert verschoben. Es ist garantiert. – StoryTeller

Antwort

7

A Wert Kopie von s wird von friend String operator+(String lhs, const String& rhs) übernommen, im Wesentlichen weil s keine ist t eine anonyme temporäre und ist daher kein geeigneter Kandidat für den Umzug. Um diesen Wert zu kopieren, wird der Kopierkonstruktor benötigt.

+1

Sie haben Recht, LHs ist eine Kopie – Nick

+0

@StoryTeller Aber das würde eine Kopie innerhalb der Methode erfordern, nicht wahr? – Nick

0

Nach meinem Verständnis wird der Kopierkonstruktor aufgerufen, um den Rückgabewert des Operators + zu erhalten.

Verwandte Themen