拷贝构造函数调用的几种情况:
当用类的一个对象去初始化该类的另一个对象(或引用)时系统自动调用拷贝构造函数实现拷贝赋值。
若函数的形参为类对象,调用函数时,实参赋值给形参,系统自动调用拷贝构造函数。(这里可有可能被编译器优化)
当函数的返回值是类对象时,系统自动调用拷贝构造函数。(注意会有编译器可能会进行优化,而观察不到拷贝的发生)
举例说明:
#include<ctime>#include<cstdlib>#include<iterator>#include<algorithm>#include<iostream>#include<numeric>using namespace std;class A {public: A():data(0){} A(const A& a){ data = a.data; cout << "拷贝构造函数调用\n"; } A& operator=(const A&a){ data = a.data; cout << "调用赋值函数\n"; return *this; } int data; };void fun1(A a) { return ; }A fun2() { A a; return a; }int main() { A a; A b(a); //用类的一个对象a去初始化另一个对象b A c = a; //用类的一个对象a去初始化另一个对象c,注意这里是初始化,不是赋值 fun1(a); //形参为类对象,实参初始化形参,调用拷贝构造函数。 A d = fun2(); //函数返回一个类对象时, 这里可能会被编译器优化,从而可能没有调用拷贝构造 d = a; //d已经初始化过了,这里是赋值,调用赋值函数 return 0; }
需要注意,在第三条:当函数的返回值是类对象时,系统自动调用拷贝构造函数。这里默认情况下一般会被编译器优化,减少不必要的拷贝构造,所以,具体的返回值可能会因编译器及编译选项的不同而不同。使用g++编译器,关闭优化g++ xxx.cpp -fno-elide-constructors后执行结果如下:
拷贝构造函数调用 拷贝构造函数调用 拷贝构造函数调用 拷贝构造函数调用 拷贝构造函数调用 调用赋值函数
默认情况下,优化后的结果如下:
拷贝构造函数调用 拷贝构造函数调用 拷贝构造函数调用 调用赋值函数
编译器具体是怎么优化的,一般编译器会先看支不支持拷贝优化,如果不支持,再看有没有定义移动构造函数,如果都没有,就调用拷贝构造函数。更具体的细节可以参考移动语义及拷贝优化的内容。
发表评论 取消回复