#include <iostream> using namespace std; class CExample { public: CExample(int x) :m_nTest(x) //带参数构造函数 { cout<< "constructor with argument."<<endl; } CExample(const CExample & ex) //拷贝构造函数 { m_nTest = ex.m_nTest; cout << "copy constructor."<<endl; } CExample& operator = (const CExample &ex)//赋值函数(赋值运算符重载) { cout << "assignment operator." << endl; m_nTest = ex.m_nTest; return *this; } void myTestFunc(CExample ex) { } private: int m_nTest; }; int main() { CExample aaa(2); CExample bbb(3); bbb = aaa; CExample ccc = aaa; bbb.myTestFunc(aaa); system("pause"); return 0; }
第一个输出: constructor with argument. //CExample aaa(2);html
这里建立了变量aaa,在建立的同时还带有参数2,那就调用带参数的构造函数ios
第二个输出:constructor with argument. //CExample bbb(3);小程序
分析同第一个安全
第三个输出:assignment operator. //bbb = aaa;函数
bbb以前已经建立了,因此这个不会调用构造函数,而只是将aaa赋值给bbb,因此调用赋值函数
第四个输出:copy constructor. //CExample ccc = aaa;this
这个和上一个的区别就在于:bbb以前已经建立过了,而这里的ccc是在这条语句才建立的,因此这里是在建立ccc的同时将aaa赋值给ccc,因此这句调用的确定是构造函数,又由于须要将aaa赋值给ccc,因此调用的是拷贝构造函数。spa
第五个输出:copy constructor. // bbb.myTestFunc(aaa);
这里是调用了一个本身写的myTestFunc函数,其中这个函数中的参数没有采用引用,那就是值传递的方式。就是编译器先建立一个类型为CExample名称为ex的对象,而后将aaa的值传递给ex(值传递方式的特性),将至关于要执行一条CExample ex = aaa的语句。经第四个输出的分析可知,这须要调用拷贝构造函数。因此输出copy constrctor。.net
【错误答案】我的第一反应:为了减小一次内存拷贝。htm
【正确答案】由上节的第五个输出分析可知,在执行bbb.myTestFunc(aaa);时,其实会调用拷贝构造函数。若是咱们的拷贝构造函数的参数不是引用,那么在bbb.myTestFunc(aaa);时,调用CExample ex = aaa;,又由于ex以前没有被建立,因此又须要调用拷贝构造函数,故而又执行CExample ex = aaa;,就这样永远的递归调用下去了。对象
因此, 拷贝构造函数是必需要带引用类型的参数的, 并且这也是编译器强制性要求的。
【正确答案】若是在函数中不会改变引用类型参数的值,加不加const的效果是同样的。并且不加const,编译器也不会报错。可是为了整个程序的安全,仍是加上const,防止对引用类型参数值的意外修改。
——若有不对的地方,很是欢迎给予指导!
——【感谢】资料来源于https://www.cnblogs.com/engraver-lxw/p/7580403.html
——【感谢】资料来源于http://blog.csdn.net/tunsanty/article/details/4264738
——【感谢】资料来源于http://blog.csdn.net/sinat_36053757/article/details/70597567