C++的拷贝构造函数和赋值函数是两个特别比较让人混淆的概念,在使用中也经常容易出错,在这里我把C++的拷贝构造函数和赋值函数总结下。我从以下几个方面来总结:
1、什么是拷贝构造函数和赋值函数,二者的区别
2、C++拷贝构造函数和赋值函数的形式 ,为什么是拷贝构造函数式这种形式
3、什么是默认拷贝构造函数和默认赋值函数
4、什么是浅拷贝和深度拷贝
5、拷贝构造函数和赋值函数使用中应该注意的问题
一、什么是拷贝构造函数和赋值函数,二者区别
首先,拷贝构造函数从名字看它是个构造函数,又加了个定语"拷贝",总结来说,拷贝构造函数是一种特殊的构造函数,它是用一个已经存在的类的对象去创建该类的一个新对象。赋值函数指对于两个已经存在的类对象,用其中一个类对象对另外一个类对象进行赋值操作,拷贝构造函数和赋值函数非常容易混淆。拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用。
请看下面例子:
String a(“hello”);
String b(“world”);
String c = a; // 虽然用了“=”,但是调用了拷贝构造函数,最好写成 c(a);
c = b; // 调用了赋值函数
本例中第三个语句的风格较差,宜改写成String c(a) 以区别于第四个语句。
二、C++拷贝构造函数和赋值函数的形式 ,为什么是拷贝构造函数式这种形式
对于Class A的拷贝构造函数的一般形式为A (A const &a),思考下为什么是这种形式,如果只是死记硬背记住了那没什么意思。
首先因为拷贝构造函数是一种特殊的构造函数,既然是构造函数,函数名称必须和类名一样,且没有返回值。那为什么参数必须是引用类型呢?如果不加引用,A(A a)会怎么样?
如果你尝试会发现编译通过不了。为什么编译通过不了,编译器为什么会报错,试想如果你这样写
Class A { public: A(A a); // 拷贝构造函数 A(int value) // 一般构造函数 { val = value; } ...... private: int val; }; |
调用应该是是这样:
A a1(7); // 调用一般构造函数
A b(a1);// 调用拷贝构造函数
注意:在调用拷贝构造函数时,会把a1的副本a1_bak传给形参a,那a1_bak又是如何产生的,“拷贝构造函数”,那拷贝构造函数呢?就是它本身!A(Aa)。这就是用需要调用自身的拷贝构造函数时又需要调用自身的拷贝构造函数,这样就会陷入无穷递归!所以编译器认为这样是不合法的!
为什么要加入const,其实不加也可以,加了就是read-only,防止在拷贝构造函数中修改源对象的内容。
赋值函数形式为:
A & A::operator =(const A &other)