簡體   English   中英

當我復制和交換成語時,為什么我的復制構造函數不被調用?

[英]why isn't my copy constructor called when I do a copy and swap idiom?

在下面的代碼中,當使用賦值運算符時,為什么沒有調用復制構造函數或為什么沒有與之對應的打印?

#include <iostream>
#include <cstring>

using std::cout;
using std::endl;

class Person {
private:
    char* name;
    int age;
public:
    Person() {
        name = nullptr;
        age = 10;
    }
    Person(const char* p_name, int p_age) {
        name = new char[strlen(p_name) + 1];
        strcpy(name, p_name);
        age = p_age;
    }

    Person(Person const& p) {
        cout << "Person copy constructor with " << p.name << endl;
        name = new char[strlen(p.name) + 1];
        strcpy(name, p.name);
        age = p.age;
    }

    /*self assignment
    The first is the self-assignment test. This check serves two purposes: it's an easy way to prevent us from running needless code on self-assignment,
    and it protects us from subtle bugs (such as deleting the array only to try and copy it). 
    But in all other cases it merely serves to slow the program down, and act as noise in the code; self-assignment rarely occurs, so most of the time 
    this check is a waste. It would be better if the operator could work properly without it.*/
    /*
    Person& operator=(Person const& p) {
        cout << "Person copy assignment with " << p.name << endl;
        if(this != &p){
            delete[] name;
            name = nullptr;
            name = new char[strlen(p.name) + 1];
            strcpy(name, p.name);
            age = p.age;
        }
        return *this;
    }
    */

    /*exception safety
    If in the previous approach the memory allocation fails and throws an exception then the data in name is gone*/
    /*
    Person& operator=(Person const& p) {
        cout << "Person copy assignment with " << p.name << endl;
        char* temp_name = new char[strlen(p.name) + 1];
        strcpy(temp_name, p.name);
        delete[] name;
        name = temp_name;
        age = p.age;
        return *this;
    }
    */

    //copy and swap idiom
    /*
    . Not only that, but this choice is critical in C++11, which is discussed later.
    (On a general note, a remarkably useful guideline is as follows: if you're going to make a copy of something in a function,
    let the compiler do it in the parameter list.‡)
    */
    Person& operator=(Person p) {
        cout << "Person copy assignment with " << p.name << endl;
        swap(*this, p);
        return *this;
    }

    /*
    A swap function is a non-throwing function that swaps two objects of a class, member for member. We might be tempted to 
    use std::swap instead of providing our own, but this would be impossible; std::swap uses the copy-constructor and 
    copy-assignment operator within its implementation, and we'd ultimately be trying to define the assignment operator in terms of itself!
    */
    friend void swap(Person &a, Person &b) {
        using std::swap;
        swap(a.name, b.name);
        swap(a.age, b.age);
    }

    Person(Person&& other) {
        swap(*this, other);
    }

    ~Person() {
        if(name)
            cout << "Person destructor called for " << name << endl;
        delete[] name;
    }
};

int main() {
    Person p("Ryan", 28);
    Person a(p);
    a = p;
    cout << "Hello World" << endl;

    return 0;
}

上面代碼的輸出是:

Person copy constructor with Ryan
Person copy constructor with Ryan
Person copy assignment with Ryan
Person destructor called for Ryan
Hello World
Person destructor called for Ryan
Person destructor called for Ryan

為什么沒有調用復制構造函數/沒有與之對應的打印。

實際上它被稱為好。 您可以在自己的輸出中看到:

Person copy constructor with Ryan
Person copy constructor with Ryan <--- This is it : )
Person copy assignment with Ryan

看這里是通話網站:

a = p;

這是你的賦值運算符:

Person& operator=(Person p) {
    cout << "Person copy assignment with " << p.name << endl;
    swap(*this, p);
    return *this;
}

所以復制構造函數在這里被調用為誰? 什么時候? 在進入operator=代碼的主體之前,正在調用此參數p (來自調用站點的=的RHS作為其參數)。 因此,在輸出中,您將其視為與此前一行相鄰的行:

Person copy assignment with Ryan

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM