如何获取指向shared_ptr的指针?

Jam*_*ond 5 c++ boost shared-ptr

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

有一个资源分配函数看起来像:

my_src_type* src;
my_src_create(&src, ctx, topic, handle_src_event, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)

我尝试用shared_ptr包装src:

shared_ptr<my_src_type> pSrc;
Run Code Online (Sandbox Code Playgroud)

我刚才忘了提.我需要做一个循环

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;
}
Run Code Online (Sandbox Code Playgroud)

我可以这样做吗?

Emi*_*ier 8

使用shared_ptrC风格的资源

使用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);
}
Run Code Online (Sandbox Code Playgroud)

在类中包装遗留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) );
}
Run Code Online (Sandbox Code Playgroud)

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

如果要MySrc复制,请确保实现复制构造函数和赋值运算符,以便执行深层复制.


jpa*_*cek 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);
Run Code Online (Sandbox Code Playgroud)

但要注意,如果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
};
Run Code Online (Sandbox Code Playgroud)

然后按照MySrc通常的方式使用共享指针。