首页 > 学院 > 开发设计 > 正文

复制构造函数

2019-11-11 05:15:44
字体:
来源:转载
供稿:网友

C++除了自动提供默认构造函数和析构函数,还有一种叫复制构造函数,用于将一个对象复制到新创建的对象中。它用于初始化过程中,而不是常规的赋值过程。原型通常如:

Classname ( const Classname & );

新建一个对象并初始化为同类现有对象时,复制构造函数都会被调用,如下4种声明:

StringBad ditto(motto);

StringBad metoo = motto;

StringBad also = StringBad(motto);

StringBad * ps = new StringBad(motto);

由于按值传递对象将调用复制构造函数,应该按引用传递对象,节省调用时间和空间。

默认的复制构造函数将逐个复制非静态成员(成员复制也称为浅复制),复制的是成员的值。如果需要用到静态成员,需要显式定义一个复制构造函数。函数头如:

StringBad::StringBad(const StringBad & s)

浅复制还有一个隐患,当成员包含指针,在调用了默认复制构造函数之后,会出现两个指针指向同一个地址的情况。此时如果用delete释放内存很容易不小心释放两次,此时将导致不确定的、可能有害的后果。解决办法是定义一个显式复制构造函数,进行深度复制!生成一个指向数据的副本,并将其地址赋给新的指针。

通常还需要看一看默认的赋值运算符。上面4种情况总是会调用复制构造函数,但使用=时也可能会调用赋值运算符(与具体实现有关,比如先用复制构造函数创建一个临时对象,然后再通过赋值将临时对象的值复制到新对象中。

赋值运算符原型:

Classname & Classname::Operator=(const Classname &);

同样必须用深度复制解决值传递出现的问题。

补充:复制构造函数与返回对象的关系

一般而言,如果方法或函数要返回局部对象,则应返回对象,而不是指向对象的引用。在这种情况下,将使用复制构造函数来生成返回的对象。如果方法或函数要返回一个没有公有复制构造函数的类(如ostream)的对象,则必须返回一个指向这种对象的引用。最后,有些方法和函数(如重载的赋值运算符)可以返回对象,也可以返回指向对象的引用,在这种情况下,应首选引用,因为其不会调用复制构造函数,效率更高。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表