C++ 拷贝构造函数和拷贝赋值运算符的区别

转自:https://www.cnblogs.com/wangguchangqing/p/6141743.html

1.区别

拷贝构造函数和赋值运算符的行为比较相似,都是将一个对象的值复制给另一个对象;

但是其结果却有些不同,拷贝构造函数使用传入对象的值生成一个新的对象的实例,而赋值运算符是将对象的值复制给一个已经存在的实例

拷贝构造函数也是一种构造函数,那么它的功能就是创建一个新的对象实例;赋值运算符是执行某种运算,将一个对象的值复制给另一个对象(已经存在的)。

调用的是拷贝构造函数还是赋值运算符,主要是看是否有新的对象实例产生。如果产生了新的对象实例,那调用的就是拷贝构造函数;如果没有,那就是对已有的对象赋值,调用的是赋值运算符

2.例子

class Person
{
public:
    Person(){cout<<"无参构造函数"<<endl;}
    Person(const Person& p)
    {
        cout << "Copy Constructor" << endl;
    }

    Person& operator=(const Person& p)
    {
        cout << "Assign" << endl;
        return *this;
    }

private:
    int age;
    string name;
};

void f(Person p)
{
    return;
}

Person f1()
{
    Person p;//无参构造函数
    return p;
}

int main(){
    Person p;          //无参构造函数
    Person p1 = p;    //  Copy Constructor
    Person p2;          //无参构造函数
    p2 = p;           //  Assign
    f(p2);            //  Copy Constructor
    cout<<"-----"<<endl;
    p2 = f1();        //  Assign
    cout<<"-----"<<endl;
    Person p3 = f1(); //
    return 0;
} #输出: 无参构造函数 Copy Constructor 无参构造函数 Assign Copy Constructor ----- 无参构造函数 Assign ----- 无参构造函数

唯一不明白的地方是最后一句,调用了f1内部创建了对象,打印“无参构造函数”,那么又赋值给p3,为什么没调用拷贝构造函数呢?不明白。

3.对指针取引用 

// 使用上面的person结构
void testfunc(Person* p){
    Person pp;
    pp = *p;
    cout<<pp.name<<"\n";
}
int main() { 
    Person p;
    p.name ="myname";

    testfunc(&p);
    cout<<endl;
    return 0;
}

// 运行输出,说明在*p时取内容并赋值是调用了赋值运算符函数
无参构造函数
无参构造函数
Assign

假设Person内部有一个简单对象:

// Person需要把拷贝operator=去掉
struct InnerSt{
    string aaa;
};

void testfunc(Person* p){
    Person pp;
    pp = *p; // 赋值时结构体对象会发生浅拷贝
    cout<<pp.name<<" "<<pp.inner.aaa<<"\n";
    cout<<p->name<<" "<<p->inner.aaa<<"\n";
}
int main() { 
    Person p;
    InnerSt st;
    st.aaa="aaaaaa";
    p.inner = st;
    p.name ="myname";

    testfunc(&p);
    cout<<endl;
    return 0;
}

// 输出
无参构造函数
无参构造函数
myname aaaaaa// Person需要把拷贝operator=去掉,不然这里不会输出
myname aaaaaa

 

posted @ 2020-10-27 19:02  lypbendlf  阅读(589)  评论(0编辑  收藏  举报