如何获取指向shared_ptr的指针?

时间:2010-03-03 13:10:10

标签: c++ boost shared-ptr

我现在正在攻击旧的C代码,尝试使其更具C ++ / Boost风格:

资源分配功能如下:

my_src_type* src;
my_src_create(&src, ctx, topic, handle_src_event, NULL, NULL);

我尝试用shared_ptr包装src:

shared_ptr<my_src_type> pSrc;

我刚才忘了提。我需要将其作为循环

std::map<string, shared_ptr<my_src_type>  > dict;
my_src_type* raw_ptr;

BOOST_FOREACH(std::string topic, all_topics)
{
    my_src_create(&raw_ptr, ctx, topic, handle_src_event, NULL, NULL);
    boost::shared_ptr<my_src_type> pSrc(raw_ptr);
    dict[topic] = pSrc;
}

我可以这样做吗?

6 个答案:

答案 0 :(得分:8)

在C风格资源上使用shared_ptr

使用boost::shared_ptr,您可以将函数指针传递给“删除器”,当引用计数达到零时将自动调用该“删除器”。此功能允许shared_ptr用于管理传统C API返回的资源。

考虑保留旧版my_src_create,并提供一个返回shared_ptr的新“工厂”功能:

void my_src_deleter(my_src_type* raw_ptr)
{
    my_src_destroy(raw_ptr);
}

typedef boost::shared_ptr<my_src_type> my_src_shared_ptr;

my_src_shared_ptr create_my_src(...)
{
    my_src_type* raw_ptr;
    my_src_create(&raw_ptr, ctx, topic, handle_src_event, NULL, NULL);
    return my_src_shared_ptr(raw_ptr, &my_src_deleter);
}

std::map<string, my_src_shared_ptr> dict;

BOOST_FOREACH(std::string topic, all_topics)
{
    dict[topic] = create_my_src(ctx, topic, handle_src_event, NULL, NULL);
}

在类中包装遗留C结构/函数

或者,(如jpalecek建议的那样)你可以将my_src包装在一个类中。遗留my_src对象的创建和销毁在构造函数和析构函数中处理。如果您要这样做,您应该考虑是否希望您的MySrc课程可以复制。如果MySrc是重量级或者是昂贵的,那么您可能希望将其设置为不可复制,并且如果要共享shared_ptr<MySrc>的所有权,请考虑使用MySrc

class MySrc
{
public:
    typedef boost::shared_ptr<MySrc> Ptr;
    MySrc(...) { my_src_create(&src_, ...); }
    ~MySrc() { my_src_destroy(&src_); }
    // Other member functions that uses my_src legacy functions

private:
    my_src_type* src_;
    // Make copy-constructor and assignment private to disallow copies
    MySrc(const MySrc& rhs) {}
    MySrc& operator=(const MySrc& rhs) {return *this;}
};

std::map<string, MySrc::Ptr> dict;

BOOST_FOREACH(std::string topic, all_topics)
{
    dict[topic] = MySrc::Ptr(
        new MySrc(ctx, topic, handle_src_event, NULL, NULL) );
}

请注意,您还可以使用MySrc类来包装在my_src实例上运行的旧函数。

如果您希望MySrc可以复制,那么请确保实现复制构造函数和赋值运算符,以便执行深层复制。

答案 1 :(得分:2)

没有

基本上,你必须用旧的C方式做,然后以某种方式将结果转换为shared_pointer

您只需初始化shared_pointer

即可
my_src_type* pSrc;
my_src_create(&src, ctx, topic, handle_src_event, NULL, NULL);
shared_ptr<my_src_type> sp(pSrc);

但请注意,如果my_src_create函数可以返回已存在的对象,则会失败。此外,如果有my_src_destroy函数,则不会调用它。

恕我直言,最简洁的方法是将您的结构包装在C ++类中:

class MySrc {
  my_src_type* pSrc;
public:
  MySrc(...) { my_src_create(&pSrc, ...); }
  ~MySrc() { my_src_destroy(&pSrc); }
private:
  MySrc(const MySrc&);
  void operator=(const MySrc&); // disallow copying
};

然后使用共享指针MySrc使用方法。

答案 2 :(得分:2)

我认为你的问题没有多大意义。如果正在重写my_src_create,则传递对共享指针的引用,或者返回共享指针。如果你没有重做那种方法那么你就不能真正做到这一点。我建议使用原始指针进行创建,然后将其包装到共享指针中:

shared_ptr<my_src_type> src;
{
   my_src_type* raw_src;
   my_src_create(&raw_src, ctx, topic, handle_src_event, NULL, NULL);
   src.reset( raw_src ); // hand ownership to shared_ptr
}

获取共享指针内的指针并修改它会破坏共享指针不变量:您将更改指针但不更新共享计数。

答案 3 :(得分:0)

你还在重做my_src_create()吗?

鉴于函数的名称,我将返回一个boost :: shared_ptr,而不是传递一个预先构建的函数,因为这是一个更清晰和更清洁的恕我直言。除非函数也返回某种失败/成功代码,但抛出异常会更好。

如果您非常想传入一个空的shared_ptr,可以通过非const引用传入它,并使用shared_ptr::reset()内的my_src_create为其分配一个新值。

答案 4 :(得分:0)

您始终可以“旧方式”执行此操作,然后使用reset()make_shared()将该src指针指定给shared_ptr。

答案 5 :(得分:0)

我会使用此代码来解决您的问题:

my_src_type* src;
my_src_create(&src, ctx, topic, handle_src_event, NULL, NULL);
boost::shared_ptr<my_src_type> pSrc(src);

从那时起pSrc将管理由my_src_type* src指向的已分配内存。

编辑:删除我的答案的错误部分。