Странное поведение для unique_pointer в Visual Studio 2010
Я пробовал написать этот класс
#include <memory>
class ContainerUnique
{
public:
ContainerUnique(void);
~ContainerUnique(void);
private:
std::unique_ptr<UniqueElement> u;
};
Где UniqueElement - класс POD, определенный в другом месте. Теперь я определяю тело конструктора следующим образом:
ContainerUnique::ContainerUnique(void)
{
auto tmp = new UniqueElement(1);
this->u(tmp); // u is a unique_ptr<UniqueElement>. Should this call compile?
}
И он соблюдает без исключений. Запустив программу, я обнаружил, что после вызова конструктора ContainerUnique
, u
содержит нулевой указатель.
Это намеченное поведение? И какой метод unique_ptr я действительно звоню?
Ответы
Ответ 1
Это известная проблема с VS2010 unique_ptr
. Она публично наследуется от своего делетера, если она пуста как оптимизация (пустая оптимизация базы). Недостатком публичного наследования является то, что все члены deleter также становятся доступными членами unique_ptr
, в этом случае его operator()(T*)
удаляет указатель.
Исправлена ошибка в библиотеке VS2012, где наследование изменено на закрытое.
Ответ 2
Вы вызываете default_delete< UniqueElement >::operator () ( UniqueElement* ptr )
, потому что uniqe_ptr извлекается из него (чтобы извлечь выгоду из пустой оптимизации базового класса) и удаляет ptr
. Это не совсем то, что вам нужно, хотя я не думаю, что стандарт запрещает это.
Ответ 3
Это должно быть сделано как
ContainerUnique::ContainerUnique(void):u(new UniqueElement(1)) {
}