O construtor de unique_ptr<T>
aceita um ponteiro bruto para um objeto do tipo T
(portanto, ele aceita a T*
).
No primeiro exemplo:
unique_ptr<int> uptr (new int(3));
O ponteiro é o resultado de uma new
expressão, enquanto no segundo exemplo:
unique_ptr<double> uptr2 (pd);
O ponteiro é armazenado na pd
variável.
Conceitualmente, nada muda (você está construindo um a unique_ptr
partir de um ponteiro bruto), mas a segunda abordagem é potencialmente mais perigosa, pois permitiria a você, por exemplo, fazer:
unique_ptr<double> uptr2 (pd);
// ...
unique_ptr<double> uptr3 (pd);
Assim, temos dois ponteiros únicos que efetivamente encapsulam o mesmo objeto (violando assim a semântica de um ponteiro único ).
É por isso que a primeira forma de criar um ponteiro exclusivo é melhor, quando possível. Observe que em C ++ 14 seremos capazes de fazer:
unique_ptr<int> p = make_unique<int>(42);
O que é mais claro e seguro. Agora, a respeito dessa sua dúvida:
O que também não está claro para mim é como os ponteiros, declarados dessa forma, serão diferentes dos ponteiros declarados de forma "normal".
Supõe-se que os ponteiros inteligentes modelem a propriedade do objeto e automaticamente cuidem da destruição do objeto apontado quando o último ponteiro (inteligente, proprietário) para esse objeto sair do escopo.
Desta forma, você não precisa se lembrar de fazer delete
em objetos alocados dinamicamente - o destruidor do ponteiro inteligente fará isso por você - nem se preocupar se você não cancelará a referência de um ponteiro (pendente) para um objeto que já foi destruído:
{
unique_ptr<int> p = make_unique<int>(42);
// Going out of scope...
}
// I did not leak my integer here! The destructor of unique_ptr called delete
Agora unique_ptr
é um ponteiro inteligente que modela a propriedade exclusiva, o que significa que a qualquer momento em seu programa deve haver apenas um ponteiro (proprietário) para o objeto apontado - é por isso que unique_ptr
não pode ser copiado.
Contanto que você use ponteiros inteligentes de uma maneira que não quebre o contrato implícito que eles exigem que você cumpra, você terá a garantia de que nenhuma memória será perdida e a política de propriedade adequada para seu objeto será aplicada. Ponteiros brutos não oferecem essa garantia.
new int(3)
retorna um ponteiro para o novoint
, assim comopd
um ponteiro para o novodouble
.