OpenJudge第二周测验—02

002:奇怪的类复制

程序填空,使得输出结果为9 22 5

#include 
using namespace std;
class Sample {
public:
	int v;
	/*--------程序填空-----*/
    Sample(int num):v(num){};
    Sample(){};
    Sample(const Sample &s){
        v = s.v + 2;
        //cout << "called!"<
    }
    /*------------------*/
};
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!"<
    }

思考
因为拷贝构造和拷贝复制常常使我们混淆,而且隐藏的比较深
所以对于这两种方式我们需要加以区分

  • 拷贝构造:用一个对象初始化另一个同类对象,这里一定是初始化,拷贝构造函数的格式为 : 构造函数名(对象的引用)
  • 拷贝复制:可以理解为赋值,这里的对象是已经定义好的,将值传过去

赋值:实质是重载赋值操作符,编译器也会默认生成,例如这里的Sample c = 20;
如果一个类没有定义任何的东西,编译器也会帮助我们生成下面的4个函数:
1、一个构造函数,也就是所谓的类名比如classname(),这是在没有定义构造函数时,编译器会自动生成的。
2、析构函数,
3、复制构造函数。
4、重载赋值操作符。

参考文章:https://blog.csdn.net/qq_36553031/article/details/89057433

你可能感兴趣的:(OpenJudge)