Использование shared_ptr
на ресурсах в стиле C
С помощью boost::shared_ptr
вы можете передать указатель функции «удалителю», который будет вызываться автоматически, когда счетчик ссылок достигнет нуля. Эта функция позволяет использовать shared_ptr для управления ресурсами, возвращаемыми устаревшими API-интерфейсами C.
Подумайте о том, чтобы оставить свое прежнее 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
можно было копировать, убедитесь, что реализовали конструктор копирования и оператор присваивания, чтобы выполнить глубокое копирование.