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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值