Il y a en effet 3 fois qu'une instance de Bla
est construit.
Bla GetBla() {
Bla bla; // 1st construction
return std::move(bla); // 2nd construction (return by copy)
}
Ne revenez pas par déménagement. Renvoyez simplement bla
, dans la plupart des cas, la copie sera élidée.
auto bla = std::make_unique<Bla>(GetBla()); // 3rd construction - Bla copy construction
Notez que make_unique<Bla>
construit toujours une nouvelle instance. Dans ce cas, parce que vous passez une autre instance, cela devient une construction de copie.
Un indice que la construction de copie a lieu est que votre constructeur par défaut n'est invoqué qu'une seule fois, tandis que le destructeur est invoqué 3 fois. C'est parce que dans les 2 autres cas, le constructeur implicite de copie (ou de déplacement) est invoqué (Bla::Bla(Bla const&)
).
Le compilateur peut même vous avertir que
Je ne suis pas sûr à 100 %, mais je pense que vous recevez les trois appels de desctructor de :
- La variable locale
bla
à partir deGetBla()
- La valeur de retour de
GetBla()
après son utilisation enstd::make_unique<Bla>(GetBla());
- Évidemment du destructeur du
std::unique_ptr
Le plus simple est de laisser std::make_uniqe
appeler le constructeur par défaut de Bla
:
auto bla = std::make_unique<Bla>(); // Calls Bla::Bla() to initalize the owned object
#include <iostream>
#include <memory>
class Bla {
public:
Bla() { std::cout << "Constructor!\n"; }
~Bla() { std::cout << "Destructor!\n"; }
};
int main() {
auto bla = std::make_unique<Bla>();
}
Sortie
Constructor!
Destructor!
La bonne façon de créer unique_ptr
:
auto bla = std::make_unique<Bla>();
Cependant, votre code crée 3 instances de Bla
:
- Objet local
bla
enGetBla()
fonction. - Valeur de retour de
GetBla()
. - Enfin,
make_unique()
crée une instance supplémentaire.
REMARQUE :
- En présence d'un destructeur défini par l'utilisateur, le compilateur ne génère pas de constructeur de déplacement, donc
GetBla()
la valeur de retour est une copie de l'objet localbla
. - Depuis
GetBla()
renvoiemove
'objet local, l'élision de copie est supprimée.