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

  这篇文章主要介绍拷贝构造函数和赋值运算符的区别,以及在何时调用拷贝构造函数,什么状况下调用赋值运算符。    ios

  拷贝构造函数和赋值运算符函数

  在默认状况下(用户没有定义,可是也没有显示的删除),编译器会自动隐式生成一个拷贝构造函数和赋值运算符,但用户可使用delete来指定不生成拷贝构造函数和赋值运算符,这样的对象就不能经过值传递,也不能进行赋值运算this

 1 #include <iostream>  2  3 using namespace std;  4 class Person {  5 public:  6  Person():{}  7 Person(const Person& p) = delete;  8 Person& operator= (const Person& p) = delete;  9 10 void SetName( string strName ) 11  { 12 name = strName; 13  } 14 void SetAge(int nAge) 15  { 16 age = nAge; 17  } 18 private: 19 int age; 20 string name; 21 }; 22 int main() 23 { 24  Person p1; 25 p1.SetName("air"); 26 p1.SetAge(18); 27 28 //Person p2(p1); 错误的 29 return 0; 30 }

上面定义的类Person显式的删除了拷贝构造函数和赋值运算符,在须要调用拷贝构造函数或者赋值运算符的地方,会提示没法调用该函数,它是已删除的函数。spa

还有一点须要注意的是,拷贝构造函数必须以引用的方式传递参数,这是由于,在值传递给一个函数的时候,会调用拷贝构造函数生成函数的实参,若是拷贝构造函数的参数仍然是以值的方式,就会无限循环的调用下去,直到函数的栈溢出。code

什么时候调用对象

  拷贝构造函数和赋值运算符的行为比较类似,都是将一个对象的值复制给另外一个对象,可是其结果却有些不一样,拷贝构造函数使用传入对象的值生成一个新的对象的实例,而赋值运算符是将对象的值复制给一个已经存在的实例。这种区别从二者的名字也能轻易的分辨出来,拷贝构造函数也是一种构造函数,那么它的功能就是建立一个新的对象实例;赋值运算符是执行某种运算,将一个对象的值复制给另外一个对象(已经存在的)。调用的是拷贝构造函数仍是赋值运算符,主要是看是否有新的对象实例产生,若是产生了新的对象实例,那调用的就是拷贝构造函数;若是没有,那就是对已有的对象赋值,调用的是赋值运算符。blog

调用拷贝构造函数主要有如下场景:编译器

  1:对象做为函数的参数,以值传递的方式传给函数。string

  2:对象做为函数的返回值,以值的方式从函数返回。io

  3:使用一个对象给另外一个对象初始化。

代码以下:

 1 #include <iostream>  2  3 using namespace std;  4 class Person  5 {  6 public:  7  Person() {}  8 Person( const Person& p )  9  { 10 cout << "Copy Constructor" << endl; 11  } 12 13 Person& operator=( const Person& p ) 14  { 15 cout << "Assign" << endl; 16 return *this; 17  } 18 19 private: 20 int age; 21 string name; 22 }; 23 24 void f( Person p ) 25 { 26 return; 27 } 28 29 Person f1( ) 30 { 31  Person p; 32 return p; 33 } 34 35 36 int main() 37 { 38  Person p; 39 Person p1 = p; // 1 40 Person p2; // 41 p2 = p; // 2 42 f(p2); // 3 43 44 p2 = f1(); // 4 45 46 Person p3 = f1(); // 5 47 48 return 0; 49 }

 

1:虽然使用了“=”,可是实际上使用对象p来建立了一个新的对象p1.也就是产生了新的对象,因此调用的是拷贝构造函数。

2:首先声明了一个对象p2,而后使用复制运算符"=",将p的值赋值给p2,显然是调用了赋值运算符,为一个已经存在的对象赋值。

3:以值传递的方式将对象p2传入函数f内,调用拷贝构造函数构建一个函数f可用的实参

4:这条语句拷贝构造函数和赋值运算符都调用了。函数f1以值的方式返回一个Person对象,在返回时会调用拷贝构造函数建立一个临时对象tmp做为返回值;返回后调用赋值运算符将临时对象tmp赋值给p2.

5:应该是首先调用拷贝构造函数建立临时对象;而后再调用拷贝构造函数使用刚才建立的临时对象建立新的对象p3,也就是会调用两次拷贝构造函数。不过,编译器也没有那么傻,应该是直接调用拷贝构造函数使用返回值建立了对象p3。

相关文章
相关标签/搜索