002:奇怪的类复制
程序填空,使得输出结果为9 22 5
#include <iostream>
using namespace std;
class Sample {
public:
int v;
/*--------程序填空-----*/
Sample(int num):v(num){};
Sample(){};
Sample(const Sample &s){
v = s.v + 2;
//cout << "called!"<<endl;
}
/*------------------*/
};
void PrintAndDouble(Sample o)
{
cout << o.v;
cout << endl;
}
int main()
{
Sample a(5);
Sample b = a;
PrintAndDouble(b);
Sample c = 20;
PrintAndDouble(c);
Sample d;
d = a;
cout << d.v;
return 0;
}
分析
首先观察Sample c = 20; PrintAndDouble(c);
这是一个初始化语句,那么会调用有一个int型参数的构造函数,假设直接把int型值赋给了v,那么c.v = 20
再调用PrintAndDouble(c);
函数,调用函数的时候,传参有两种方式
- 传值
- 传地址(在这里是传引用)
对于传值:看这一段代码,从c到Sample o之间,因为Sample o还未初始化,所以传参的过程隐含了复制构造函数,因此分析出来,复制构造函数中对v增了2,我们需要重写拷贝构造函数
PrintAndDouble(c);
void PrintAndDouble(Sample o)
{
cout << o.v;
cout << endl;
}
如果加上cout进行测试,我们可以发现,通过拷贝构造后,v增加了2
Sample c = 20;
cout << c.v << endl;
PrintAndDouble(c);
因此重写拷贝构造函数,将v增2
Sample(const Sample &s){
v = s.v + 2;
//cout << "called!"<<endl;
}
思考:
因为拷贝构造和拷贝复制常常使我们混淆,而且隐藏的比较深
所以对于这两种方式我们需要加以区分
- 拷贝构造:用一个对象初始化另一个同类对象,这里一定是初始化,拷贝构造函数的格式为 : 构造函数名(对象的引用)
- 拷贝复制:可以理解为赋值,这里的对象是已经定义好的,将值传过去
赋值:实质是重载赋值操作符,编译器也会默认生成,例如这里的Sample c = 20;
如果一个类没有定义任何的东西,编译器也会帮助我们生成下面的4个函数:
1、一个构造函数,也就是所谓的类名比如classname(),这是在没有定义构造函数时,编译器会自动生成的。
2、析构函数,
3、复制构造函数。
4、重载赋值操作符。
参考文章:https://blog.csdn.net/qq_36553031/article/details/89057433