为什么复制构造函数的参数需要加const和引用
Posted Engraver
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么复制构造函数的参数需要加const和引用相关的知识,希望对你有一定的参考价值。
为什么复制构造函数的参数需要加const和引用
一.引言
1.0在解答这个问题之前,我们先跑个小程序,看下调用关系。
1 #include <iostream>
2 using namespace std;
3 class CExample
4 {
5 public:
6 CExample(int x) :m_nTest(x) //带参数构造函数
7 {
8 cout<< "constructor with argument."<<endl;
9 }
10 CExample(const CExample & ex) //拷贝构造函数
11 {
12 m_nTest = ex.m_nTest;
13 cout << "copy constructor."<<endl;
14 }
15 CExample& operator = (const CExample &ex)//赋值函数(赋值运算符重载)
16 {
17 cout << "assignment operator." << endl;
18 m_nTest = ex.m_nTest;
19 return *this;
20 }
21 void myTestFunc(CExample ex)
22 {
23 }
24 private:
25 int m_nTest;
26 };
27
28 int main()
29 {
30 CExample aaa(2);
31 CExample bbb(3);
32 bbb = aaa;
33 CExample ccc = aaa;
34 bbb.myTestFunc(aaa);
35 system("pause");
36 return 0;
37 }
1.1【输出结果】
1.2【分析结果】
第一个输出: constructor with argument. //CExample aaa(2);
这里创建了变量aaa,在创建的同时还带有参数2,那就调用带参数的构造函数
第二个输出:constructor with argument. //CExample bbb(3);
分析同第一个
第三个输出:assignment operator. //bbb = aaa;
bbb之前已经创建了,所以这个不会调用构造函数,而只是将aaa赋值给bbb,所以调用赋值函数
第四个输出:copy constructor. //CExample ccc = aaa;
这个和上一个的区别就在于:bbb之前已经创建过了,而这里的ccc是在这条语句才创建的,所以这里是在创建ccc的同时将aaa赋值给ccc,所以这句调用的肯定是构造函数,又因为需要将aaa赋值给ccc,所以调用的是拷贝构造函数。
第五个输出:copy constructor. // bbb.myTestFunc(aaa);
这里是调用了一个自己写的myTestFunc函数,其中这个函数中的参数没有采用引用,那就是值传递的方式。就是编译器先创建一个类型为CExample名称为ex的对象,然后将aaa的值传递给ex(值传递方式的特性),将相当于要执行一条CExample ex = aaa的语句。经第四个输出的分析可知,这需要调用拷贝构造函数。所以输出copy constrctor。
二.解答问题
2.1为什么要用引用?
【错误答案】个人第一反应:为了减少一次内存拷贝。
【正确答案】由上节的第五个输出分析可知,在执行bbb.myTestFunc(aaa);时,其实会调用拷贝构造函数。如果我们的拷贝构造函数的参数不是引用,那么在bbb.myTestFunc(aaa);时,调用CExample ex = aaa;,又因为ex之前没有被创建,所以又需要调用拷贝构造函数,故而又执行CExample ex = aaa;,就这样永远的递归调用下去了。
所以, 拷贝构造函数是必须要带引用类型的参数的, 而且这也是编译器强制性要求的。
2.2为什么要用const?
【正确答案】如果在函数中不会改变引用类型参数的值,加不加const的效果是一样的。而且不加const,编译器也不会报错。但是为了整个程序的安全,还是加上const,防止对引用类型参数值的意外修改。
——如有不对的地方,非常欢迎给予指导!
——【感谢】资料来源于http://blog.csdn.net/tunsanty/article/details/4264738
——【感谢】资料来源于http://blog.csdn.net/sinat_36053757/article/details/70597567
以上是关于为什么复制构造函数的参数需要加const和引用的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::pair 对于 const 引用和转发引用参数有两个不同的构造函数?