什么是拷贝构造函数:
拷贝构造函数,顾名思义,就是在拷贝的时候调用的构造函数。
几个原则:
C++ primer p406 :拷贝构造函数是一种特殊的构造函数,具有单个形参,该形参(常用const修饰)是对该类类型的引用。当定义一个新对象并用一个同类型的对象对它进行初始化时,将显示使用拷贝构造函数。当该类型的对象传递给函数或从函数返回该类型的对象时,将隐式调用拷贝构造函数。
C++支持两种初始化形式:
拷贝初始化 int a = 5; 和直接初始化 int a(5); 对于其他类型没有什么区别,对于类类型直接初始化直接调用实参匹配的构造函数,拷贝初始化总是调用拷贝构造函数,也就是说:
A x(2); //直接初始化,调用构造函数
A y = x; //拷贝初始化,调用拷贝构造函数
必须定义拷贝构造函数的情况:
只包含类类型成员或内置类型(但不是指针类型)成员的类,无须显式地定义拷贝构造函数也可以拷贝;有的类有一个数据成员是指针,或者是有成员表示在构造函数中分配的其他资源,这两种情况下都必须定义拷贝构造函数。
什么情况使用拷贝构造函数:
类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:
(1)一个对象以值传递的方式传入函数体
(2)一个对象以值传递的方式从函数返回
(3)一个对象需要通过另外一个对象进行初始化。
拷贝构造函数的一般形式:
classname (const classname &obj) { // 构造函数的主体 }
以下代码可以很好地测试拷贝构造函数:
#include<iostream>
class A {
public:
A(int a) {
std::cout << "调用了传统构造函数" << std::endl;
temp = a;
}
~A() {
}
A(const A &obj){
std::cout << "调用了拷贝构造函数" << std::endl;
temp = obj.temp + 1;
}
int temp;
};
A foo(A a) {
std::cout << a.temp << std::endl;
return a;
}
int main()
{
A a1(5); // 调用传统构造函数
A a2(10); // 调用传统构造函数
A a3 = a2; // 调用拷贝构造函数
std::cout << a1.temp << " " << a2.temp << " "<< a3.temp << std::endl;
A a4 = foo(a3); // 会调用两次拷贝构造函数,传参时调一次,return时调一次
std::cout<< a4.temp << std::endl;
}
运行结果:
调用了传统构造函数
调用了传统构造函数
调用了拷贝构造函数
5 10 11
调用了拷贝构造函数
12
调用了拷贝构造函数
13
网友评论