Я преподавал себе умные указатели, которые являются частью С++ 0x, и наткнулся на то, что кажется мне непоследовательным. В частности, как обрабатываются политики уничтожения unique_ptr < > и shared_ptr < > .
Для unique_ptr < > вы можете специализировать std:: default_delete < > и затем, если вы явно не запрашиваете другую политику уничтожения, будет использоваться новый по умолчанию.
Рассмотрим следующее:
struct some_c_type;
some_c_type *construct_some_c_type();
void destruct_some_c_type(some_c_type *);
namespace std {
template <> struct default_delete<some_c_type> {
void operator()(some_c_type *ptr) {
destruct_some_c_type(ptr);
}
};
}
Теперь, как только это произойдет, unique_ptr < > будет использовать соответствующую политику уничтожения по умолчанию:
// Because of the specialization, this will use destruct_some_c_type
std::unique_ptr<some_c_type> var(construct_some_c_type());
Теперь сравните это с shared_ptr < > . С shared_ptr < > вам нужно явно запросить соответствующую политику уничтожения или по умолчанию использовать оператор delete:
// error, will use operator delete
std::shared_ptr<some_c_type> var(construct_some_c_type());
// correct, must explicitly request the destruction policy
std::shared_ptr<some_c_type> var(construct_some_c_type(),
std::default_delete<some_c_type>());
Два вопроса.
- Правильно ли, что shared_ptr < > требует, чтобы политика уничтожения была указана каждый раз, когда она использовалась, или я что-то не хватает?
- Если я чего-то не упускаю, любая идея, почему эти две разные?
P.S. Причина, по которой я забочусь об этом, - моя компания делает много смешанных программ на C и С++. Код С++ часто должен использовать объекты стиля C, поэтому для меня довольно простота определения различной политики уничтожения по умолчанию.