• 在返回值拒绝——reference


    在上一篇博客中,我们介绍了简单地使用值传递带来的种种麻烦,相信有些朋友会一心一意将其斩草除根,但是当返回值也使用了引用的时候,麻烦就来了。
    依然来个简答的例子

    class Rational
    {
    public:
        Rational(int numerator = 0,int denominator = 1);
    private:
        const Rational& operator*(const Rational& lhs,const Rational& rhs);
    };
    

    operator的返回值是一个reference。记得那句话吗?“引用是另外一个变量的别名”,那么问题就来了,operator返回的引用是谁的别名。假如我们返回的是一个局部变量,那么这个家伙在函数返回的时候实际上已经不存在了。也就是说,这个时候返回的reference,是“以前的,已经不存在的一个变量的别名”。而假如我们使用一个不存在的东西,我们也将一败涂地。这个时候,我们考虑在heap(堆)上创建一个对象。

    const Rational& operator*(const Rational& lhs,const Rational& rhs)
    {
        Rational *result = new Rational();
        return *result;
    }
    

    让我们回溯到提醒我们使用引用的原因上:避免太大的消耗。这个主要体现在构造函数与析构函数上,而上述的例子中,很明显我们又回到了解决问题之前,又得付出一个构造函数的代价。但是,更不妥的是,下面这个例子。

        Rational w,x,y,z;
        w = x * y * z;
    

    x * y将会在heap上new Rational()产生一个Rational_1,然后这个Rational_1的引用与z又将会在heap上new Rational()产生一个Rational_2,然后这个Rational_2将会被w持有。在程序结束的时候,我们使用delete w销毁了Rational_2,那么,Rational_1呢?很明显,我们造成了内存泄露。

    从上面的描述我们可以发现,不管是在stack或者在heap上,返回一个reference都会受到惩罚。那么函数返回一个对象的正确写法是什么呢?就是”让函数返回一个对象呗“虽然,这有可能给性能造成一定的拖累,但是它能保证这是正确的。

  • 相关阅读:
    基本指令
    javascript event(事件对象)详解
    Sass进阶之路,之二(进阶篇)
    Sass进阶之路,之一(基础篇)
    原型链进阶
    数据类型检测
    JavaScript引用类型和值类型
    i.mx6 Android6.0.1分析input子系统:测试
    (三)JNI常用示例
    (二)JNI方法总结
  • 原文地址:https://www.cnblogs.com/suimeng/p/4885639.html
Copyright © 2020-2023  润新知