【问题标题】:Is it considered good style to dereference `new` pointer?取消引用`new`指针是否被认为是好的风格?
【发布时间】:2013-05-07 19:52:16
【问题描述】:

为了避免继续使用-> 而是直接使用对象,是否可以这样做:

obj x = *(new obj(...));
...
delete &obj;

【问题讨论】:

    标签: c++ pointers new-operator dereference


    【解决方案1】:

    这不仅是糟糕的做法,而且:

    1. 内存泄漏(很可能,除非您使用的模式在您提供的代码中不可见),因为obj 将存储由@987654322 创建的原始对象的副本 @ 表达式,而 new 返回的指向该对象的指针丢失;
    2. 最重要的是,未定义的行为,因为您正在向delete 传递一个指向未使用new 分配的对象的指针。根据 C++11 标准的第 5.3.5/2 段:

    [...] 在第一种选择(删除对象)中,delete 的操作数的值可能是空指针 值,指向由前一个 new-expression 创建的非数组对象的指针,或指向子对象的指针 (1.8) 表示这种对象的基类(第 10 条)。 如果不是,则行为未定义

    【讨论】:

    • 第二个胜过第一个。他不会泄漏内存,因为程序可能不会运行足够长的时间让他进行多次分配。
    • 嗯,至少可以做到obj &x = *new
    【解决方案2】:

    不,实际上这会导致泄漏。 x复制初始化,所以new obj 指向的原始对象丢失了。

    随便用

    obj x(...);
    

    无需动态分配。或者

    obj x = obj(...);
    

    如果你必须(怀疑)。

    【讨论】:

    • 或者你可以使用参考obj& = (*new ...
    • @Marcin 你可以,但是为什么呢?
    • @Marcin 是的,你可以。您也可以将键盘砸到屏幕上。仅仅因为你可以,并不意味着你应该。 :)
    • @JamesKanze 因为 OP 希望一直避免取消引用,这就是引用的用途。
    • @Marcin 如果您遵循 Luchian 的建议,您不必取消引用。
    【解决方案3】:

    当然不是;将动态对象复制到自动变量,丢失指向它的唯一指针,然后尝试删除自动副本。您有内存泄漏和无效删除。

    首先使用自动变量会更好:

    obj x(...);
    ...
    // no need to delete anything
    

    或者,如果由于某种原因它真的必须是动态的(因为它对于堆栈来说太大了,或者你并不总是想在这里销毁它),然后使用智能指针,如果你真的不这样做,则使用引用喜欢->

    std::unique_ptr<obj> p(new obj(...));
    obj & x = *p;
    ...
    // still no need to delete anything
    

    将您的 x 更改为引用是有效的(只要您注意异常、早期函数返回等不会导致泄漏),但会在不幸的任何人中引起混乱必须维护它。

    【讨论】:

      【解决方案4】:

      如果你这样做,你将无法正确删除你的对象。

      您隐式执行以下操作。

      class A
      {
      public:
        int test (void) { return 1; }
      };
      
      int main (void)
      {
        A * p = new A;
        A v(*p);
        //...
        delete &v; // &v != p and v is not constructed via new!
        return 0;
      }
      

      如果您想使用类似对象的语法,您可以绑定对对象的引用。

      class A
      {
      public:
        int test (void) { return 1; }
      };
      
      int main (void)
      {
         A * p = new A;
         A & r = *p;
         int i = r.test();
         delete p;
         return 0;
      }
      

      如果你通过同一个指针删除你的对象,就不会有泄漏。

      【讨论】:

        猜你喜欢
        • 2012-05-06
        • 2023-03-16
        • 2016-02-10
        • 2017-02-17
        • 1970-01-01
        • 1970-01-01
        • 2015-02-12
        • 1970-01-01
        相关资源
        最近更新 更多