【问题标题】:How to reuse object created in the stack如何重用堆栈中创建的对象
【发布时间】:2014-07-04 05:38:54
【问题描述】:

我不是 C++ 程序员,我非常尊重它的复杂性,所以我通常会远离它。尽管如此,我还是找到了一个我想修改的库。

该库包含一个示例 sn-p,其中在本地范围内分配了一个实例:

    Foo foo(arg1, arg2, ...);

我想修改这个例子来重新初始化对象并用它做更多的事情,但我不能通过 getter/setter 或公共变量来做。在不创建更多实例的情况下这是否可能?

如果不创建新实例就无法做到这一点,我如何释放不再需要的对象的内存?

例如,如果它是一个动态对象,我想它会是这样的:

    Foo* pfoo;

    pfoo = new Foo(arg1, arg2, ...);
    pfoo->doSomething();
    delete pfoo;

    pfoo = new Foo(arg3, arg4, ...);
    pfoo->doSomething();
    delete pfoo;

堆栈中分配的对象的等价物是什么?

【问题讨论】:

  • “重新初始化”对象是什么意思?我假设你的意思是再次调用构造函数,但是你提到了一些关于 getter/setter 的东西。这是Calling a constructor to re-initialize object 的可能重复项吗?
  • 您的两个选择是 setter/getter 或制作一个全新的对象。既然你说不能用前者,那你就得新建一个对象Foo foo2(arg3, arg4, ..)
  • c++的方式是一个对象做一件事。你不能只创建两个对象吗?
  • @MisterSmith:你的第二个例子通常是糟糕的风格。您不会在 C++ 中“重用”这样的指针。您只需创建第二个指针,除非您在极其特殊的环境中或使用非常笨拙的遗留代码开发软件。

标签: c++ object constructor stack


【解决方案1】:

释放自动变量的唯一方法是让它们超出范围:

void bar() {
  Foo f1(arg1, arg2);
  f1.doSomething();

  {
    Foo f2(arg3, arg4);
    f2.doSomething();
    // other stuff ...
    // f2 dies here.
  }

  {
    Foo f3(arg5, arg6); // allocated on stack, possibly overlapping f2's old spot
    f3.doSomething();
    // ...
    // f3 dies here.
  }

  // f1 dies here.
}

【讨论】:

  • 不是唯一的方式。您可以使用新展示位置 - Foo f(arg3, arg4); f.~Foo(); new(&f) Foo(arg5, arg6);
  • 好的,放置new 也可以,但是对于普通的自动对象来说,这比傻瓜更疯狂。 :) 公平地说,我说的是 release,你的示例最终仍然需要 f
【解决方案2】:

如果一个对象不允许通过公共设置器重新初始化自己 - 你不能这样做。

实际上,在您的示例中,您并没有重新初始化 object,而是创建了 Foo 的另一个实例,并使用该对象的地址重新初始化了一个 指针变量

局部变量的生命周期仅限于它们的范围。因此,您可以将函数的范围拆分为更小的范围:

void bar()
{
  {
    Foo foo(arg1, arg2, ...);
    foo.doSomething();
  }
  {
    Foo foo(arg3, arg4, ...);
    foo.doSomething();
  }
}

【讨论】:

    【解决方案3】:

    只是想为 OP 再发布一个替代方案,更符合他的建议:

    void somefunction()
    {
        // create the first foo owned by a smart pointer
        std::unique_ptr<Foo> pFoo { new Foo { arg1, arg2, ... } };
        pFoo->doSomething();
    
        // now replace the old Foo with a new one
        pFoo.reset( new Foo { arg3, arg3, ... } );
        pFoo->doSomething();
    
        // no need to delete anything unless you specifically want the Foo to die now
        // in which case...
        // pFoo.reset();
    } // implicit destruction of whatever pFoo owns happens here
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-15
      • 1970-01-01
      • 2020-04-09
      • 2012-08-12
      • 2010-09-24
      • 1970-01-01
      • 2010-12-08
      相关资源
      最近更新 更多