zoukankan      html  css  js  c++  java
  • 关于返回局部引用 ,局部new的指针

    看到effective c++上总结的

    class rational{

    public:

      rational(int numerator=0,int denominator=1);

         friend const rational& operator*(const rational&lhs,

      const rational&rhs);

    private:

    int n,d;

    }

    inline const rational& operator*(const rational&lhs,const rational&rhs)

    {

       rational result(lhs.n*rhs.n,lhs.d*rhs.d);

       return result;

     }

    然后你这样调用

    rational two=2;

    rational  four=two*two;

    函数调用时将发生如下事件:

    1. 局部对象result被创建。
    2. 初始化一个引用,使之成为result的另一个名字;这个引用先放在另一边,留做operator*的返回值。
    3. 局部对象result被销毁,它在堆栈所占的空间可被本程序其它部分或其他程序使用。
    4. 用步骤2中的引用初始化对象four.

    记住是先构造result,再析构result,最后copy cons,所以最后可能有问题。

    new一样,直接贴了

    第一,大家都知道,程序员这类人是很马虎的。这不是指你马虎或我马虎,而是指,没有哪个程序员不和某个有这类习性的人打交道。想让这样的程序员记住无论何时调用operator*后必须得到结果的指针然后调用delete,这样的几率有多大呢?也是说,他们必须这样使用operator*:

    const rational& four = two * two;      // 得到废弃的指针;
                                           // 将它存在一个引用中
    ...

    delete &four;                          // 得到指针并删除

    这样的几率将会小得不能再小。记住,只要有哪怕一个operator*的调用者忘了这条规则,就会造成内存泄漏。

    返回废弃的指针还有另外一个更严重的问题,即使是最尽责的程序员也难以避免。因为常常有这种情况,operator*的结果只是临时用于中间值,它的存在只是为了计算一个更大的表达式。例如:

    rational one(1), two(2), three(3), four(4);
    rational product;

    product = one * two * three * four;

    product的计算表达式需要三个单独的operator*调用,以相应的函数形式重写这个表达式会看得更清楚:

    product = operator*(operator*(operator*(one, two), three), four);

    是的,每个operator*调用所返回的对象都要被删除,但在这里无法调用delete,因为没有哪个返回对象被保存下来。

    解决这一难题的唯一方案是叫用户这样写代码:

    const rational& temp1 = one * two;
    const rational& temp2 = temp1 * three;
    const rational& temp3 = temp2 * four;

    delete &temp1;
    delete &temp2;
    delete &temp3;

    果真如此的话,你所能期待的最好结果是人们将不再理睬你。更现实一点,你将会在指责声中度日,或者可能会被判处10年苦力去写威化饼干机或烤面包机的微代码。

    所以要记住你的教训:写一个返回废弃指针的函数无异于坐等内存泄漏的来临。

    另外,假如你认为自己想出了什么办法可以避免"返回局部对象的引用"所带来的不确定行为,以及"返回堆(heap)上分配的对象的引用"所带来的内存泄漏,那么,请转到条款23,看看为什么返回局部静态(static)对象的引用也会工作不正常。看了之后,也许会帮助你避免头痛医脚所带来的麻

  • 相关阅读:
    企业搜索引擎开发之连接器connector(二十九)
    solr&lucene3.6.0源码解析(四)
    solr&lucene3.6.0源码解析(三)
    elasticsearch 7.7.0 最新版+Java High Level REST Client测试
    自制聊天软件测试
    网页正文内容抽取测试
    Kernel Functions for Machine Learning Applications
    Latent semantic analysis note(LSA)
    jQuery插件备忘
    比较成系列的文章[备份.感谢这些作者的辛苦]
  • 原文地址:https://www.cnblogs.com/cavehubiao/p/3444460.html
Copyright © 2011-2022 走看看