通过智能指针获取所有权,并通过相同的智能指针进一步访问原始指针

时间:2014-08-01 23:15:39

标签: c++ c++11 smart-pointers

我有一个像这样的漏洞代码:

void f() {
  SomeClass *sc = new SomeClass;
  ...
  if (...) {
    g(sc); // g() takes ownership of memory pointed to by sc
  }
  ...
  sc->SomeMethod();
  ...
}

我想通过使用智能指针消除泄漏,想到以下解决方案:

void f() {
  smart_ptr<SomeClass> sc(new SomeClass);
  ...
  if (...) {
    g(sc.release()); // ownership is taken
  }
  ...
  sc->SomeMethod(); // sc points to the allocated memory regardless of whether ownership was taken or not
  ...
} // the memory is freed if ownership was not taken

尝试使用std :: unique_ptr和std :: shared_ptr。 std :: unique_ptr在发布后指向空指针,std :: shared_ptr根本没有release()。手动增加std :: shared_ptr的引用计数器会有所帮助,但正如我所理解的那样,也没有这样的能力。

除了将原始指针保留为原始指针以及每次将原始指针传递给取得所有权的函数时调用release()之外,还考虑使用std :: unique_ptr,但这是一个非常混乱的解决方案。 / p>

我想知道标准库中是否有适合我目标的智能指针, 或者在我的案例中可能有一个想法或常见的伎俩,或者我可能遗漏了什么?

3 个答案:

答案 0 :(得分:3)

您可以使用更多代码保留本地非拥有视图:

void g(std::unique_ptr<Foo> p);     // takes ownership

int main()
{
    auto p = std::make_unique<Foo>();
    Foo & local_view = *p;

    if (/* condition */) { g(std::move(p)); }

    local_view.do_stuff();
}

答案 1 :(得分:0)

我不明白你对g取得所有权的意思,因为在g退出后你仍然会使用指针。如果你总是想在g之后使用指针,那么将原始指针传递给g并在块的末尾释放指针会更有意义。

如果您确实希望g取得所有权,并且只想在指针仍然存在的情况下调用SomeMethod,请将原始指针传递给g并让它返回原始指针。如果指针在g中取消分配,请返回nullptr并在SomeMethod调用之前检查该指针。

答案 2 :(得分:0)

您可以使用shared_ptr同等效果。 shared_ptr没有release()函数,但它具有reset()函数,这是我认为您正在寻找的函数。但是,您必须等到拨打SomeClass::SomeMethod()之后再拨打sc.reset()

void g(shared_ptr<SomeClass> ptr);

void f()
{
   shared_ptr<SomeClass> sc(new SomeClass);

   if (/* check for condition */)
   {
      g(sc);
   }

   sc->SomeMethod();
   sc.reset();
}