请帮忙运行一下代码,然后解释一下析构函数的作用,谢谢
代码一:内容为在复数类中定义了构造函数、复制构造函数、析构函数、运算符重载+的函数,以及一个void display()成员函数,有两个私有成员都是double类型的。
#include "iostream.h "
using namespace std;
class complex
{
double real;
double imag;
public:
complex(double r=0.0,double i=0.0)
{
real=r;
imag=i;
cout < < "构造( " < <real < < ", " < <imag < < ") " < <endl;
}
~complex()
{
cout < < "析构( " < <real < < ", " < <imag < < ") " < <endl;
}
complex(const complex &c)
{
real=c.real;
imag=c.imag;
cout < < "复制( " < <real < < ", " < <imag < < ") " < <endl;
}
complex operator + (const complex &x)
{
double r=real+x.real;
double i=imag+x.imag;
cout < < "运算符重载 " < <endl;
return complex(r,i);
}
void display()
{
cout < < "( " < <real < < ", " < <imag < < ") " < <endl;
}
};
int main()
{
complex A(3.0,5.0),B(2.0,3.0);
complex C=A+B;
C.display();
return 0;
}
代码二:内容为将上述复数类中的析构函数去掉后,执行同样的int main()函数。
#include "iostream.h "
using namespace std;
class complex
{
double real;
double imag;
public:
complex(double r=0.0,double i=0.0)
{
real=r;
imag=i;
cout < < "构造( " < <real < < ", " < <imag < < ") " < <endl;
}
complex(const complex &c)
{
real=c.real;
imag=c.imag;
cout < < "复制( " < <real < < ", " < <imag < < ") " < <endl;
}
complex operator + (const complex &x)
{
double r=real+x.real;
double i=imag+x.imag;
cout < < "运算符重载 " < <endl;
return complex(r,i);
}
void display()
{
cout < < "( " < <real < < ", " < <imag < < ") " < <endl;
}
};
int main()
{
complex A(3.0,5.0),B(2.0,3.0);
complex C=A+B;
C.display();
return 0;
}
以上两组代码中唯一不同的地方就是在类中是否显式定义了析构函数,发现执行同样的int main()代码,两组执行的结果不同,不知道哪位能帮忙解释一下其中的原因。谢谢!
[解决办法]
这是一个涉及到代码优化的主题。在下述操作符重载函数中
complex operator + (const complex &x)
{
double r=real+x.real;
double i=imag+x.imag;
cout < < "运算符重载 " < <endl;
return complex(r,i);
}
complex(r,i)是一个构造函数,围绕它是否产生临时变量,构成了优化的课题
在不优化的情况下,complex(r,i)将产生一个临时变量,然后返回时又产生一个临时变量。象这样:
//情况一,编译器对 return complex(r,i); 的处理,不做返回值优化
complex _lc = complex(r,i); // 1)调用一次构造函数
complex _ret = _lc; // 2)调用一次拷贝构造函数
complex C = _ret; // 3)从operator + 返回,调一次拷贝构造函数
然后就可以对它优化,因为多次可拷贝不必要。如可以省略临时变量_lc,形成情况二
//情况二,编译器对 return complex(r,i); 的处理,返回值优化:省略临时变量_lc
complex _ret = complex(r,i); // 1)调用一次构造函数
complex c = _ret; // 2)从operator + 返回,调一次拷贝构造函数
还有进一步优化,如省略临时变量_ret,形成情况三
//情况三,编译器对 return complex(r,i); 的处理,返回值优化:省略临时变量_lc,_ret
complex C = complex(r,i); // 1)从operator + 返回,直接用C代替返回值,调用一次构造函数
自从有了情况三,情况二就比较少了,只有再具名返回值优化中才可能出现。
而是否做优化,怎样做优化,C++标准没有规定,各个编译器可以自行决定。
至于析构函数的作用,则被一些编译器作为是否优化的开关。
一种观点是:当出现显示定义的析构函数时,说明构造/析构的代价很大,应该做优化;而当不出现构造函数时,可以不优化。
另一种观点正好相反:当出现显示定义的析构函数时,为了保证它的负作用(side effect),应该不做优化,这也被成为优化压抑;而不出现构造函数时,可以优化。
这也是由编译器决定的。如VC6使用的是第一种观点,而VC8则无论如何都做优化。
所以,可以试试自己的编译器是采用怎样的优化策略,或者从它的文档中查明。