首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么当我执行复制和交换习惯用法时,我的复制构造函数没有被调用?

为什么当我执行复制和交换习惯用法时,我的复制构造函数没有被调用?
EN

Stack Overflow用户
提问于 2018-09-17 17:21:32
回答 1查看 117关注 0票数 1

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

代码语言:javascript
复制
#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;
}

上述代码的输出为:

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2018-09-17 18:32:40

为什么没有调用复制构造函数/没有与之对应的打印。

实际上,它被调用得很好。你可以在你自己的输出中看到:

代码语言:javascript
复制
Person copy constructor with Ryan
Person copy constructor with Ryan <--- This is it : )
Person copy assignment with Ryan

下面是调用点:

代码语言:javascript
复制
a = p;

这是你的赋值操作符:

代码语言:javascript
复制
Person& operator=(Person p) {
    cout << "Person copy assignment with " << p.name << endl;
    swap(*this, p);
    return *this;
}

那么这里的复制构造函数是为谁调用的?什么时候?它是在进入operator=代码体之前为参数p (使用来自调用点的=的RHS作为参数)调用的。因此,在输出中,您可以将其视为紧邻此行之前的行:

代码语言:javascript
复制
Person copy assignment with Ryan
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52364499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档