Complex num1(1, 2);
Complex num2(3, 5);
Complex result = num1 * num2;
如果要实现 operator* 函数, 函数内需要创建一个Complex对象并返回
方法一:在stack空间创建对象
const Complex& operator*(const Complex& lhs, const Complex& rhs)
{
Complex result(lhs.real * rhs.real, lhs.imaginary * rhs.imaginary);
return result;
}
问题:
- 该函数返回一个reference指向result,但result是local对象,而local对象在函数退出前就被销毁了,因此函数返回的reference指向一个被销毁的Complex。
方法二:在heap空间创建对象
const Complex& operator*(const Complex& lhs, const Complex& rhs)
{
Complex *result = new Complex(lhs.real * rhs.real, lhs.imaginary * rhs.imaginary);
return *result;
}
问题:
会导致内存泄漏
Complex res, x, y, z; res = x * y * z;
在上述代码中,调用两个operator*,也就是调用两个new,然而没有相应地调用delete函数,导致内存泄漏。
方法三:创建一个static对象
const Complex& operator*(const Complex& lhs, const Complex& rhs)
{
static Complex result;
resule = Complex(lhs.real * rhs.real, lhs.imaginary * rhs.imaginary);
return result;
}
问题:
在如下代码
Complex a, b, c, d; if ((a * b) == (c * d)) { ………… }
代码中,左右两个operator*返回的reference指向同一个static对象,因此operator==总是true。
方法四:返回一个object
const Complex operator*(const Complex& lhs, const Complex& rhs)
{
return Complex(lhs.real * rhs.real, lhs.imaginary * rhs.imaginary);
}
对于operator*函数来说,直接返回一个新对象避免了返回reference的问题,但仍然需要承担构造函数的析构函数的开销。
总结:
- 上述方法一到方法三都是返回reference的错误例子,如果你选择返回一个reference时,一定要避免上述情况;
- 如果你遇到了一个“必须返回新对象”的函数(如上述operator*),请直接返回一个新对象。