3、复制构造函数

1、复制构造函数的特点

  • 只有一个参数,即对同类对象的引用
  • 形如 X::X( X& )或X::X(const X &), 二者选一(后者能以常量对象作为参数)。即:形参要么是 对同类对象的引用要么是对同类对象的常量引用
  • 如果没有定义复制构造函数,那么编译器生成默认复制构造函数。默认的复制构造函数完成复制功能。

注意:一个类中一定会有复制构造函数,要么是自己写的要么是编译器自动生成的,这与默认构造函数有所不同。编译器自动生成的复制构造函数完成的是对象间的拷贝工作。程序员自己写的复制构造函数完成的并不一定是对象间的复制工作,虽然道理上它应该完成对象间的复制工作,这取决于程序员自己。
2、复制构造函数起作用的三种情况

  • 当用一个对象去初始化同类的另一个对象时。
  • 如果某函数有一个参数是类 A 的对象,那么该函数被调用时,类A的复制构造函数将被调用。
  • 如果函数的返回值是类A的对象时,则函数返回时,A的复制构造函数被调用。
//情况一:
Complex c2(c1);
Complex c2 = c1; //初始化语句,非赋值语句
//情况二:
class A
{
public:
	A() { };
	A( A & a) {
		cout << "Copy constructor called" <<endl;
	}
}

void Func(A a1){ }
int main(){
A a2;
Func(a2);
return 0;
}
//情况三
class A
{
public:
	int v;
	A(int n) { v = n; };
	A( const A & a) {
		v = a.v;
		cout << "Copy constructor called" <<endl;
	}
};


A Func() {
A b(4);
return b;
}

int main() {
	cout << Func().v << endl; return 0;
}

注意:对象间赋值并不导致复制构造函数被调用。

class CMyclass {
public:
	int n;
	CMyclass() {};
	CMyclass( CMyclass & c) { n = 2 * c.n ; }
};

int main() {
		CMyclass c1,c2;
		c1.n = 5; c2 = c1; CMyclass c3(c1); //对象间赋值
		cout <<"c2.n=" << c2.n << ",";
		cout <<"c3.n=" << c3.n << endl;
		return 0;
}
输出: c2.n=5,c3.n=10

3、常量引用的使用

void fun(CMyclass obj_ ) {
	cout << "fun" << endl;
}

这样的函数,调用时生成形参会引发复制构造函数调用,开销比较大。所以可以考虑使用 CMyclass & 引用类型作为参数。如果希望确保实参的值在函数中不应被改变,那么可以加上const 关键字。

void fun(const CMyclass & obj) {
	//函数中任何试图改变 obj值的语句都将是变成非法
}

4、常量引用作为函数形参的好处:

  • 节省复制拷贝函数被调用的开销。
  • 防止原始数据被意外的修改。
posted @ 2019-11-24 20:11  江南又一春  阅读(552)  评论(0编辑  收藏  举报