C++ 为什么在执行复制和交换习惯用法时不调用复制构造函数?

C++ 为什么在执行复制和交换习惯用法时不调用复制构造函数?,c++,copy-constructor,assignment-operator,copy-and-swap,C++,Copy Constructor,Assignment Operator,Copy And Swap,在下面的代码中,当使用赋值运算符时,为什么不调用复制构造函数,或者为什么没有对应的打印 #include <iostream> #include <cstring> using std::cout; using std::endl; class Person { private: char* name; int age; public: Person() { name = nullptr; age = 10;

在下面的代码中,当使用赋值运算符时,为什么不调用复制构造函数,或者为什么没有对应的打印

#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;
}
为什么没有调用复制构造函数/没有对应的打印

事实上,大家都说它很好。您可以在自己的输出中看到:

与Ryan合作的人员 与Ryan合作的人员 为什么没有调用复制构造函数/没有对应的打印

事实上,大家都说它很好。您可以在自己的输出中看到:

与Ryan合作的人员
和Ryan在一起的人你说不打印是什么意思?第二行就是这样。你还指望什么?为什么要关门?根据输出,复制构造函数被调用得很好:我猜OP希望复制构造函数消息出现在复制分配消息之后。这不是重复的,至少是前面提到的。复制构造函数未按预期删除。事实上,复制构造函数是在赋值之前调用的,与打印行对应。操作:尝试在a=p行之前插入打印@怀疑论者经济学家你现在有机会完成你的回答:什么是不打印?第二行就是这样。你还指望什么?为什么要关门?根据输出,复制构造函数被调用得很好:我猜OP希望复制构造函数消息出现在复制分配消息之后。这不是重复的,至少是前面提到的。复制构造函数未按预期删除。事实上,复制构造函数是在赋值之前调用的,与打印行对应。操作:尝试在a=p行之前插入打印@怀疑论专家您现在有机会完成您的答案:
a = p;
Person& operator=(Person p) {
    cout << "Person copy assignment with " << p.name << endl;
    swap(*this, p);
    return *this;
}