[effectiv c++]条款21:返回reference 与 返回object

来源:互联网 发布:人工智能简介 编辑:程序博客网 时间:2024/06/05 20:36
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*),请直接返回一个新对象。
阅读全文
0 0
原创粉丝点击