C++复制构造函数
图:广州天河CBD
Guderian出品
本文整理自《北京大学公开课:C++面向对象程序设计》基本概念
- 只有一个参数,即对同类对象的引用
- 形如
X::X(X &)
或X::X(const X &)
,二者选一,后者能以常量对象作为参数 - 如果没有定义复制构造函数,那么编译器生成默认的复制构造函数。默认的复制构造函数完成复制功能
构造函数与复制构造函数的异同
- 构造函数(或称无参构造函数)不一定存在,你不写构造函数,编译器就只会帮你生成一个什么也不做的无参构造函数
- 复制构造函数一定存在,你不写复制构造函数,编译器也会帮你写好一个具有复制功能的复制构造函数
1 | class Complex |
- 如果定义了自己的复制构造函数,则默认的复制构造函数不存在
1 | class Complex |
特别强调1
注意:不允许有形如X::X(X)
的复制构造函数,参数一定是引用,不能是对象
1 | class CSample |
复制构造函数起作用的三种情况
(1)当用一个对象去初始化同类的另一个对象时
1 | Complex c2(c1); |
(2)当某函数有一个参数是类A的对象时
那么该函数被调用时,类A
的复制构造函数将被调用。C++
规则:形参是实参的拷贝
1 | class A |
(3)当函数的返回值是类A的对象时
那么在函数返回时,A
的复制构造函数被调用,作用是初始化作为返回值的类A
对象
1 | class A |
特别强调2
注意:对象间赋值并不导致复制构造函数被调用
1 | class CMyClass |
定义函数时常量引用参数的使用
1 | void fun(CMyClass obj) |
- 这样的函数,调用时生成形参会引发复制构造函数调用,复制一遍时间开销比较大
- 所以可以考虑使用
CMyClass &
引用类型作为参数,本质上与实参是一样的 - 如果希望确保实参的值在函数中不应被改变,那么可以加上
const
关键字,这样的话如果你定义的函数中出现了改变实参的值得语句。编译器就会报错
我自己写的程序难道我自己不记得我没有改过参数吗?的确,你现在记得,明天也记得,但以后再改你的程序,就未必记得了。从代码规范的角度来讲,加上
const
关键字是必要的
1 | void fun(const CMyClass &obj) |
思考:为什么要自己写复制构造函数?
想通这个问题是高难度操作,作者水平有限,无法清晰地回答,仅提供参考链接。
前置知识:
- 深拷贝、浅拷贝
- 传值、传地址、传引用
参考链接:
参考并整理自《C++面向对象设计》郭炜,北京大学,感谢原作者!编辑时有删改