【问题标题】:Easier way to have shared_ptr own an existing pointer让 shared_ptr 拥有现有指针的更简单方法
【发布时间】:2014-12-04 20:16:57
【问题描述】:

许多程序员提倡使用make_shared,因为它减少了键入并减少了编程错误。然而,在某些情况下,使用shared_ptr 的构造函数是不可避免的。其中一种情况是当您有一个希望shared_ptr 拥有的现有指针时,因为shared_ptr<Foo>(&existing_ptr) 是错误代码。相反,您必须使用笨拙的shared_ptr<Foo>(shared_ptr<Foo>(), p)。您不仅在重复自己,而且还必须创建一个临时对象。

int main()
{
    using namespace std;

    Foo foo;
    foo.n = 1;
    {
        auto ptr = make_shared<Foo>(move(foo));
        ptr->n = 42;
        cout << ptr->n << " " << foo.n << '\n';
    }
    {
        auto p = &foo;
        auto ptr = shared_ptr<Foo>(shared_ptr<Foo>(), p);
        ptr->n = 42;
        cout << ptr->n << " " << foo.n << '\n';
    }

    return 0;
}
Foo::Foo()
Foo::Foo(Foo &&)
42 1
Foo::~Foo()
42 42
Foo::~Foo()

shared_ptr 拥有现有指针的更简洁的方法是什么?

【问题讨论】:

  • &amp;existing_ptr 显然是错误的——你的意思是&amp;existing_object
  • shared_ptr&lt;Foo&gt;(&amp;existing_ptr) 完全不正确,但shared_ptr&lt;Foo&gt;(existing_ptr) 有什么问题?
  • @n.m.在这种情况下,shared_ptr 将尝试在销毁时删除指针,这将失败,因为指针未指向使用 new 分配的对象。
  • @MMarkRansom 想要一个无法删除的东西的 shared_ptr 有什么意义?
  • @n.m.不幸的是,有些人已经养成了在他们的函数签名中使用它的习惯,即使在不合适的时候也强迫你使用它。

标签: c++ c++11 memory memory-management shared-ptr


【解决方案1】:

IMO 你在那里做的事情不应该容易,因为它非常危险,而且只有在高度专业化的情况下才需要,在这种情况下输入两次类名应该是你最不必担心的。 p>

但这里有一个更简洁的方法,通过使用虚拟删除器来实现相同的目标:

auto ptr = std::shared_ptr<Foo>(&foo, [](void*){});

另外,在你的方法中,说ptr 拥有 foo 是不正确的;相反,它拥有空的std::shared_ptr&lt;Foo&gt; 中的空对象,并且指向 foo(请参阅this answer 以获得更长的讨论)。在我上面的代码中,它在某种技术意义上确实“拥有”foo(或者至少它认为是这样);当它的引用计数达到零时,它只是被阻止对它做任何事情。

【讨论】:

    【解决方案2】:

    该构造函数的预期用途是允许共享指针指向共享指针的子对象。

    您的用途不是预期用途,而且非常危险,因为您已隐含地创建了一个保证,即您传递给共享指针的数据将持续与共享指针或其副本一样长,然后未能在任何有意义的意义上执行该保证。

    如果您将共享指针传递给函数,则它有权缓存一个副本并在 15 分钟后使用它。如果您没有将共享指针传递给函数,则不需要。

    一般来说,如果一个函数打算以一种难以预测的方式延长其参数的生命周期,它应该只需要一个共享指针。因此,如果您有一个函数采用共享指针并且从不延长其生命周期(或指向它的指针的生命周期),那么它不应该采用共享指针。问题出在您正在调用的函数上,而不是您必须如何跳槽才能调用它。

    只有当你俩都有一个功能坏了,并且无法修复它并且在免费商店复制Foo过于昂贵,你的技术值得一试吗?无论如何,这应该是极端的极端情况。

    【讨论】:

    • 我同意,也没有太大意义
    猜你喜欢
    • 2020-09-28
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 2014-12-16
    • 2010-10-11
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    相关资源
    最近更新 更多