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