提问者:小点点

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


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

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的引用计数器会有所帮助,但正如我正确理解的那样,没有这样的能力。

除了原始指针之外,我还考虑使用std::unique_ptr,使代码保持原样,每次将原始指针传递给取得所有权的函数时只调用release(),但这是一个非常混乱的解决方案。

我想知道是否有一个智能指针从标准库适合我的目标,或者也许有一个想法或常见的技巧如何做在我的情况下,或者我可能遗漏了什么?


共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();
}

匿名用户

我不理解您关于取得所有权的意思,因为在退出之后,您仍然要使用指针。如果您总是希望在之后使用指针,那么将一个原始指针传递给,并在块的末尾释放该指针会更有意义。

如果您确实希望获得所有权,并且希望仅当指针仍然存在时才调用,请将一个原始指针传递给,并让它返回一个原始指针。如果指针在中释放,则返回并在调用之前检查该指针。

匿名用户

您可以使用具有同等的效果。没有函数,但它有函数,我认为您正在寻找这一函数。但是,您必须等到调用之后才能调用

void g(shared_ptr<SomeClass> ptr);

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

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

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