2015-07-23 43 views
5

Ho una classe che ha un metodo setter che accetta un argomento unique_ptr. Quel unique_ptr viene salvato come membro della classe.Come distruggere prematuramente un puntatore intelligente

class TestClass { 
    std::unique_ptr<Tester> sp; 

    void setTester_Way1(std::unique_ptr<Tester> te) { 
     auto deleter=std::move(sp); 
     sp=std::move(te); 
    } 

    void setTester_Way2(std::unique_ptr<Tester> te) { 
     sp=std::move(te); 
    } 
}; 

Quale è il modo corretto di impostare il puntatore intelligente? Way2 perde il puntatore originale di sp?

+4

C'è solo un modo per scoprire un 'unique_ptr': la funzione membro' release() ' – emlai

+1

Penso che questa risposta spieghi tutto http://stackoverflow.com/questions/8114276/how-do-i-pass-a -unique-ptr-argument-to-a-constructor-or-a-function – vim

+0

@zenith è una sfida? – Yakk

risposta

6

Way2 va bene, quando si assegna a un unique_ptr qualsiasi puntatore di proprietà esistente verrà eliminato in modo sicuro.

2

Come Chris Drew, detto Way2 va bene. Una cosa però è che unique_ptr non è copiabile/assegnabile quindi l'unico modo per passare un unique_ptr è per riferimento, riferimento valore r o per valore con move(). Cercando di fare:

int main() 
{ 
    TestClass t; 
    auto p = std::make_unique<int>(10); 
    t.setTester_Way2(p); 
} 

Will fail to compile. Sebbene sia possibile immettere move()p nella funzione (example).

Se si modifica setTester_Way2() a void setTester_Way2(std::unique_ptr<int>& te)then it will compile. Se si modifica la funzione di prendere un riferimento rvalue e std::move() il puntatore nella funcnction:

class TestClass { 
    std::unique_ptr<int> sp; 
public: 

    void setTester_Way1(std::unique_ptr<int> te) { 
     auto deleter=std::move(sp); 
     sp=std::move(te); 
    } 

    void setTester_Way2(std::unique_ptr<int>&& te) { 
     sp=std::move(te); 
    } 
}; 

int main() 
{ 
    TestClass t; 
    auto p = std::make_unique<int>(10); 
    t.setTester_Way2(std::move(p)); 
} 

Then it will also compile.

+2

Stai suggerendo che _should_ passerà per riferimento? Perché in questo caso penso che il pass-by-value [va bene] (http://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/). –

+0

@ChrisDrew Personalmente mi piace tramite il riferimento al valore r poiché chiarisce che lo spostate. A meno che non sia ancora di base sulla semantica del movimento. – NathanOliver

+5

passa per riferimento al valore r _does_ rendi chiaro che lo sposti. È solo un riferimento, non viene spostato fino a quando la funzione non decide di spostarlo. Di valore _guarantees_ verrà spostato, non c'è altro modo di ottenere il parametro in là –