I am now hacking an old C code, try to make it more C++/Boost style:
there is a resource allocation function looks like:
my_src_type* src;
my_src_create(&src, ctx, topic, handle_src_event, NULL, NULL);
i try to wrap src by a shared_ptr:
shared_ptr<my_src_type> pSrc;
I forgot to mention just now. I need to do this as a loop
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;
}
Can I do it like this?
The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.
The weak_ptr class template stores a "weak reference" to an object that's already managed by a shared_ptr. To access the object, a weak_ptr can be converted to a shared_ptr using the shared_ptr constructor or the member function lock.
when all shared_ptr's pointing to resource goes out of scope the resource is destroyed. A weak_ptr is created as a copy of shared_ptr. It provides access to an object that is owned by one or more shared_ptr instances but does not participate in reference counting.
Returns the stored pointer.
shared_ptr
on C-style resourcesWith boost::shared_ptr
, you can pass a function pointer to a "deleter" that will be called automatically when the reference count reaches zero. This feature allows shared_ptr to be used to manage resources returned by legacy C APIs.
Consider leaving your legacy my_src_create
intact, and provide a new "factory" function that returns a 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);
}
Alternatively, (as jpalecek suggested) you can wrap my_src
in a class. Creation and destruction of legacy my_src
objects is handled in the constructor and destructor. If you're going to do this, you should think about whether or not you want your MySrc
class to be copyable. If MySrc
is heavyweight or expensive to create, you'll probably want to make it non-copyable and consider using shared_ptr<MySrc>
if there is going to be shared ownership of 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) );
}
Note that you can also use the MySrc
class to wrap legacy functions that operate on my_src instances.
If you want MySrc
to be copyable, then make sure to implement the copy-constructor and assignment operator so that a deep-copy is performed.
No.
Basically, you have to do it the old C way and then convert the result to a shared_pointer
somehow.
You can do it by simply initializing the shared_pointer
my_src_type* pSrc;
my_src_create(&src, ctx, topic, handle_src_event, NULL, NULL);
shared_ptr<my_src_type> sp(pSrc);
but beware, this will fail if the my_src_create
function can return an already existing object. Also, if there is a my_src_destroy
function, it won't be called.
IMHO the cleanest way is to wrap your structure in a C++ class:
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
};
and then use shared pointer for MySrc
the ususal way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With