Le seguenti situazioni implicano il trasferimento della proprietà da uno unique_ptr
a un altro: il ritorno da una funzione e il passaggio come parametro a una funzione come un costruttore.
Diciamo che avete un certo tipo polimorfico Animal
:
struct Animal {
virtual ~Animal() {}
virtual void speak() = 0;
};
con sottoclassi concrete Cat
e Dog
:
struct Cat : Animal {
void speak() override { std::cout << "Meow!\n"; }
};
struct Dog : Animal {
void speak() override { std::cout << "Woof!\n"; }
};
E si desidera una semplice fabbrica che crea un animale sulla base di un valore richiesto di obbedienza . Quindi la fabbrica deve restituire un puntatore. Vogliamo che la fabbrica di animale domestico per trasferire la proprietà degli animali da compagnia creata per il chiamante in modo un tipo di ritorno ragionevole è std::unique_ptr<Animal>
:
std::unique_ptr<Animal> createPet(double obedience) {
if (obedience > 5.0)
return std::make_unique<Dog>();
return std::make_unique<Cat>();
}
Ora, diciamo che vogliamo creare un House
che sarà proprio l'animale poi si potrebbe desiderare di passare l'animale domestico nel costruttore di House
. C'è un certo dibattito (see comments on this blog post) sul modo migliore per passare un unique_ptr
a un costruttore, ma sarebbe simile a questa:
class House {
private:
std::unique_ptr<Animal> pet_;
public:
House(std::unique_ptr<Animal> pet) : pet_(std::move(pet)) {}
};
Abbiamo passato il unique_ptr
al costruttore e abbiamo poi "spostato" agli Stati variabile.
Il codice chiamante potrebbe somigliare:
auto pet = createPet(6.0);
House house(std::move(pet));
Dopo aver costruito il House
, la variabile pet
sarà nullptr
perché abbiamo trasferito la proprietà dell'animale al House
.
Live demo
fonte
2014-10-12 02:44:42
Questo è tutto. I puntatori intelligenti nella libreria standard non dovrebbero essere visti come puntatori che sono automaticamente liberati, ma in termini di * proprietà *. Disponi di dati che possono essere "posseduti" solo da una singola entità, quindi utilizzare indicatori univoci. –
È utile quando si lavora con dati non copiabili come thread o socket ed è necessario sostituirlo da un posto a altro (ad esempio, per inserirlo nel vettore). – wowofbob