我现在正在攻击旧的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;
}
我可以这样做吗?
答案 0 :(得分:8)
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);
}
或者,(如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
指向的已分配内存。
编辑:删除我的答案的错误部分。