复制构造函数
《c++ Primer Plus(第五版)中文版》中
第385页中写道:
假设motto是一个StringBad对象,则下面4中声明都将是调用复制构造函数(及拷贝构造函数):
StringBad ditto (motto);
StringBad metoo = motto;
StringBad also = StringBad(motto);
StringBad * pStringBad = new StringBad (motto);
以上4中方式都将调用:StringBad(const StringBad &)
其中中间两种声明可能会使用复制构造函数直接创建metoo和also对象,也可能使用复制构造函数生成一个临时对象,然后将临时对象的内容赋给metoo和also,这取决于具体的实现。最后一种声明使用motto初始化一个匿名对象,并将新对象的地址赋给pStringBad指针。
每当程序生成了对象副本时,编译器都将使用复制构造函数。具体的说,当函数按值传递对象或函数返回对象时,都将使用复制构造函数。记住,按值传递意味着创建原始变量的一个副本。
编译器生成临时对象时,也将使用复制构造函数。例如,将3个Vector对象相加时,编译器可能生成临时的Vector对象来保存中间的结果。
赋值操作符
C++允许类对象赋值,这是通过自动为类重载赋值操作符实现的。这种操作符的原型如下:
Class_name & Class_name::operator=(const Class_name &);
它接受并返回一个指向类对象的引用。
将已有的对象赋给另一个对象时,将使用重载的赋值操作符:
StringBad headline1("Celery Stalks at Midnight");
.......
StringBad knot;
knot=headline1; 使用了赋值操作符
初始化对象时,并不一定会使用赋值操作符:
StringBad metoo=knot;
这里,metoo是一个新创建的对象,被初始化为knot的值,因此使用赋值构造函数。不过,正如前面指出的,实现时也可能分两步来处理这条语句:使用复制构造函数创建一个临时对象,然后通过赋值操作符将临时对象的值复制到新对象中。这就是说,初始化总是会调用复制构造函数,而使用=操作符时也可能调用赋值构造函数。
//*******************************************************************************
以上为书中语句,后从网上找到关于两者区别的一段话觉得很好,记在下面:
赋值运算符(注意,不是“赋值构造函数”)和拷贝构造函数都是用已有的对象来创建另一个对象。不同之处在于:拷贝构造函数是生成一个全新的对象,即
A a (b);//这才是C++风格的初始化
A a = b;//注意,这种风格只是为了与C兼容
在这之前a对象是不存在的,或者说还没有构造好。
赋值operator =()是两个对象都已经构造好的情况下使用的。即
a = b;
的时候,a和b都已经初始化过了(这里的“初始化过”包括默认的构造函数初始化)。