+操作符定义为成员:
A A::operator+(const A &obj)
{
A tmp;
tmp.i = i + obj.i;
return tmp;
}
A::A(const A &obj):i(obj.i)
{
std::cout << "A copy constructor" << std::endl;
}
1: A a1, a2;
2: A a3(a1 + a2); 或者 A a3 = a1 + a2;
按说在使用小括弧()初始化对象时应该使用拷贝构造函数把a1+a2后返回的的临时对象拷贝到a3,但是执行2时为什么没有调用拷贝构造函数?
csdn上有同学说是被编译器优化了,暂且只能这样认为了,在找到确切答案之前。
经过验证:
//c.h defined class CC
//
class CC
{
public:
CC();
CC(int v1, int v2);
//virtual ~CC() { std::cout << "CC DeConstructor ~CC(); j = " << j << std::endl; };
CC(const CC &obj);
CC operator+(const CC &obj);
int j;
private:
int a;
};
//c.cpp
#include "iostream"
#include "c.h"
CC::CC():a(0)
{
//std::cout << "CC Default constructor CC();" << std::endl;
}
CC::CC(int v1, int v2):a(v1), j(v2)
{
//std::cout << "CC constructor CC(int v1); j = " << j << std::endl;
}
CC::CC(const CC &obj):a(obj.a),j(obj.a)
{
std::cout << "CC Copy constructor CC(const CC &obj); j = " << j << std::endl;
}
CC CC::operator+(const CC &obj)
{
//std::cout << "CC operator+(const CC obj);" << std::endl;
CC tmp;
tmp.a = a + obj.a;
tmp.j = -1;
return tmp;
//return (CC(a+obj.a, -1));
}
//main.cpp
#include "c.h"
#include <iostream>
using namespace std;
int test(CC o);
int main()
{
CC c1(1, 1), c2(2, 2);
CC c3(c1 + c2);
return 0;}
-------------------------------------------------------
结果:
显式定义析构函数时:(return tmp时没有调用,在+操作符返回后,调用了拷贝构造函数一次,将返回的临时对象复制到a3)
CC Copy constructor CC(const CC &obj); j = 3
注释掉显式定义的析构函数时:(return tmp时调用了一次,目的是拷贝临时对象;在+操作符返回后,也调用了拷贝构造函数一次,将返回的临时对象复制到a3)
CC Copy constructor CC(const CC &obj); j = 3
CC Copy constructor CC(const CC &obj); j = 3
-------------------------------------------------------
原因分析:
1. 当没有显式定义析构函数时,编译器认为程序中没有动态资源分配,也没有对动态资源的一系列操作,就不会产生由于动态资源带来的效率问题,这个时候即使拷贝对象多次/释放对象多次也无所谓,当然了这个对象很大时拷贝多次也会带了效率问题;
2. 反之,当显式定义析构函数时,编译器认为程序中存在动态资源分配以及对动态资源的一系列操作,如果拷贝多次就会降低效率,于是编译器就直接将加操作符返回的临时对象直接拷贝到a3中,而在return tmp时省略了一次调用;