功能:使用一个已经存在的对象来初始化一个新的同一类型的对象
声明:只有一个参数,并且参数为该类对象的引用
#include <iostream>
using namespace std;
class Test
{
private:
int num_;
};
int main()
{
Test t;
Test t1(t);
return 0;
}
如果不显示的定义拷贝构造函数的话,系统会默认生成一个拷贝构造函数,上述代码就是正确的
语法: 因为拷贝构造函数也是构造函数所以没有返回值类型,名字与类名相同
类名 (类类型 &other)
形参一定要是引用,如果不是引用的话,在实参传递给形参的时候也会调用拷贝构造函数,这样然后拷贝拷贝构造函数就会无限的被循环下去
拷贝构造函数被调用的几种情况:
(1)形参为对象本身时,调用函数时,实参出师话形参调用拷贝构造函数
(2)函数的返回值为类对象时,调用拷贝构造函数,建立一个临时对象
下面看一段程序:
#include <iostream>
using namespace std;
class Test
{
private:
int num_;
public:
Test(int num=0)
{
num_ = num;
cout<<"create"<<num_<<endl;
}
Test(const Test& other) //&是必须的
{
num_ = other.num_;
cout<<"copy"<<num_<<endl;
}
Test &operator=(const Test& other)
{
num_ = other.num_;
cout<<"======"<<num_<<endl;
return *this;
}
~Test()
{
cout<<"destroy"<<num_<<endl;
}
};
void fun(const Test t) //形参为对象时,实参参初始化形参会调用拷贝构造函数
{
}
void fun1(const Test &t)//形参为对象的引用时,实参初始化形参不会调用拷贝构造函数
{
}
Test fun2(const Test &t)//返回类对象时,调用拷贝构造函数
{
return t; //返回的t不是参数中的t了,因为要去拷贝构造一个临时对象
}
Test &fun3(const Test &t) //返回引用
{
return const_cast<Test &>(t);
}
int main()
{
Test t1(20);
fun(t1); //调用拷贝构造,临时对象会立即销毁
fun1(t1); //不调用拷贝构造
Test t2(30);
fun2(t2); //调用拷贝构造函数,临时对象会立即销毁
Test t5(40);
Test t3 = fun2(t5); //注意,不会调用两次拷贝构造函数,只对临时对象改名,变成了有名对象而已,对象不会被销毁
Test t6(50);
Test &t4 = fun2(t6); //调用拷贝构造函数,临时对象不会立即销毁
Test t7(60);
fun3(t7); //不会调用拷贝构造函数
Test t8(70);
Test t9 = fun3(t8); //调用拷贝构造,但是和t3的调用拷贝构造是不一样的,这里的拷贝构造是在=处
cout<<"==========="<<endl; //根据看析构函数出现在这个语句前还是后来观察对象啥时候销毁
return 0;
}
程序运行结果如下图所示: