zoukankan      html  css  js  c++  java
  • 全面推行使用智能指针的权利

    今天,我们讨论了使用的功能返回一个指向下一个潜在的错误。如果有一个函数返回一个指针MyClass对象的指针类型。

    MyClass* MyFactoryClass::Create(const Inputs& inputs);

    这个函数的一个非常显而易见的问题是。它的调用者是否负责删除这个对象?或者说这个指针所指向的MyClass类的实例是MyFactoryClass所拥有的实例?这个问题显然应该在声明这个函数的头文件里以凝视的形式说明。但在软件的世界里,实际上非常少可以做到这样。

    可是。即使函数的作者确实提供了一个凝视。表示这个函数在堆上创建了一个新对象,而且由它的调用者负责删除这个对象,我们将会发现自己面临这样一种处境:每当我们接到一个由函数调用所返回的指向某个对象的指针时,我们须要记得检查凝视(或者在没有凝视时,检查代码本身)来判断是否由我们负责删除这个对象。

    正如前面所说的,我们应该很多其它地依赖编译器而不是程序猿。因此。实行这个对象全部权的一种可靠方法是让函数返回一个智能指针。

    比如:

    RefCountPtr<MyClass> MyFactoryClass::Create(const Inputs& inputs);

    这样的设计使函数所返回的对象的全部权毫无争议,不会留下内存泄露的机会。还有一方面,假设认为引用计数指针速度过慢不适合须要,也能够返回一个作用域指针。但这样就产生了一个问题:ScopedPtr<MyClass> 无法被复制。因此不能依照传统方法返回:

    ScopedPtr<MyClass> MyFactoryClass::Create(const Inputs& inputs)
    {
    	ScopedPtr<MyClass> result(new MyClass(inputs));
    	return result; //无法通过编译
    }

    因此,解决问题的方法例如以下:

    ScopedPtr<MyClass> result;//创建一个空的作用域指针
           //填充它
    void MyFactoryClass::Create(const Inputs& inputs,ScopedPtr<MyClass>& result);

    我们创建一个包括NULL值的作用域指针。并让MyFactoryClass::Create()方法填充他。

    这种方法也不会使这个函数所创建的对象的全部权出现错误。假设不确定应该返回哪种指针,能够选择下列方案之中的一个:

    • 假设须要,返回速度更快的ScopedPtr。并使用它的Release()方法转移全部权。
    • 同一时候通过两种方法
    另一种相反的情况是,SomeClass::Find()方法返回一个指向一个对象的指针,但用户并不拥有这个对象的全部权:

    //返回一个指向一个结果的指针,调用者“并不拥有这个结果的全部权”
    MyClass* SomeClass::Find(const Inputs& inputs);

    这样的情况下,这个函数所返回的指针,指向属于SomeClass内部的某个对象的一个对象。

    对于上述第一个问题,SomeClass类觉得自己将负责删除它刚返回的那个指针所指向的MyClass实例。因此会在未来的某个时刻将它删除。

    在这样的情况下。假设这个函数的用户将删除他所接收到的指针。这个实例将被删除不止一次。这显然不是个好主意。其次,这个实例可能是一个vector模板中使用new[]操作符(带方括号)创建的一个MyClass对象数组的一部分,而如今我们将使用不带方括号的delete操作符从这个数组中删除一个对象。

    这相同不是个好的做法。最后,MyClass实例可能是在堆栈上创建的,根本不应该使用delete操作符进行删除。

    在这样的情况下,不论什么试图删除我们并不拥有的对象的行为(直接删除。或者把它赋值给一个将接收对象全部权的不论什么类型的智能指针)将会导致灾难。

    返回这样的指针的一种合适的方法是返回一个”半智能“指针,它并不拥有它所指向的对象的全部权。

    总结:为了避免内存泄露,建议遵从下面规则:

    • 每次使用new操作符创建一个对象时,马上把结果赋值给一个智能指针(推荐使用引用计数指针或作用域指针)
    • 使用new操作符时不要带方括号。假设创建一个数组,能够创建一个新的vector模板,它表示单个对象。
    • 避免循环引用
    • 在制备指针返回到功能时,它应该返回一个智能指针而不是原始指针,为了落实没事的结果。


  • 相关阅读:
    pat00-自测5. Shuffling Machine (20)
    Spiral Matrix
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Best Time to Buy and Sell Stock II
    4Sum
    3Sum Closest
    3Sum
    MySQL存储过程、函数和游标
    Word Ladder
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5032483.html
Copyright © 2011-2022 走看看