【问题标题】:convert pointer to shared_ptr将指针转换为 shared_ptr
【发布时间】:2009-05-20 12:02:31
【问题描述】:

我有一些返回指向对象 (B) 的指针的库代码(我不能不更改源代码)。我想将此指针作为 shared_ptr 存储在具有此类构造函数的类下:

class A
{
  public:
   A(boost::shared_ptr<B> val);
   ...
  private:
   boost::shared_ptr<B> _val;
   ...
};

int main()
{
   B *b = SomeLib();
   A a(b); //??
   delete b;
   ...
} 

也就是说,我想做一个b的深拷贝,并控制它在a下的生命周期(即使原始b被删除(删除b),我在a下仍然有一个精确的副本)。

我是新来的,如果它看起来微不足道,对不起......

【问题讨论】:

    标签: c++ pointers


    【解决方案1】:

    如果库定义了这个 B 对象,库应该提供(或完全禁止)复制 B 的机制。

    作为旁注,

    如果您的 A 类专门控制此复制对象的生命周期,那么您真正要使用的智能指针是 boost::scoped_ptr

    boost::shared_ptr 以其分担终身责任的能力命名,这听起来像是你不想要的。 scoped_ptr 不会让这种意外发生。

    【讨论】:

    • 或者只是班级的一员。
    【解决方案2】:

    正如您所说,您必须复制它们而不仅仅是复制指针。因此,要么 B 已经实现了“克隆”方法,要么您必须实现一些外部 B* copy(B* b),这将创建具有相同状态的新 B。

    如果 B 已经实现了复制构造函数,您可以将复制实现为

    B* copyOf(B* b)
    {
        return new B(*b);
    }
    

    如果 B 实现了clone method or similar,您可以实现复制为

    B* copyOf(B* b)
    {
        return b->clone();
    }
    

    然后您的代码将如下所示

    int main()
    {
       B *b = SomeLib();
       A a(copyOf(b));
       delete b;
       ...
    }
    

    【讨论】:

    • 看不到函数copy的使用...
    • 主函数第二行
    • @Mykola:我明白了——但我不明白:这根本没有意义。对不起。
    • 代码现在按照问题的要求执行。它使 B 只接受指针。所以如果你想传递一个副本,如果你不传递一个指针。如果让 B 在构造函数中复制指针,则会限制 B 的功能。
    • 我已将 'copy' 更改为 'copyOf' 以强调它是一个函数。
    【解决方案3】:

    深复制在 C++ 中由复制构造函数轻松实现,因为在 C++ 中,所有 对象默认具有值语义。但是,以这种方式复制不适用于多态对象——在这种情况下,您必须在您的类中实现一个虚拟覆盖的 clone 方法。

    但在所有其他情况下,只需编写

    A(boost::shared_ptr<B> val) : _val(new B(*val)) { }
    

    会的。

    【讨论】:

    • +1。我看不出有任何理由不赞成您的回答。恰恰相反。
    • Mykola:什么原始指针?这是不可能的。这个答案完全正确。
    • 首先 - 我没有减去你,只是警告。这是警告:如果 B 在内部创建了一些对象并将它们存储以供使用并且 B 没有实现复制构造函数,则默认复制构造函数只会复制指向对象而不是对象的指针,因此在析构函数中每个 B 将删除相同的数据.
    • Mykola:嗯,没错——这是在 C++ 中定义和预期的行为,如果需要,提供适当的复制构造函数是 B 的工作。但是,这永远不会使我上面的代码(这是惯用的 C++)无效。这只是意味着 B 可能有错误。
    • 没错,正如我所说 - 这只是一个警告,以节省将来回答者的时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 2012-11-27
    • 2017-02-12
    • 1970-01-01
    相关资源
    最近更新 更多