2016-06-16 8 views
3
#include <iostream> 
#include <memory> 
using namespace std; 

int main() { 
    std::unique_ptr<int> ptrA = std::make_unique<int>(10); 

    ptrA = std::make_unique<int>(20); // case I 

    return 0; 
} 


#include <iostream> 
#include <memory> 
using namespace std; 

int main() { 
    std::unique_ptr<int> ptrA = std::make_unique<int>(10); 

    ptrA = nullptr;     // case II or ptrA.reset() 
    ptrA = std::make_unique<int>(20); 

    return 0; 
} 

Ich habe viele Leute gesehen Case II verwenden. Allerdings ist std::unique_ptr ein intelligenter Zeiger, ich denke nicht, dass wir entweder nullptr zuweisen oder reset anrufen sollten, bevor wir ihm einen neuen Wert zuweisen.sollte `nullptr` zu` std :: unique_ptr` zuweisen, bevor ihm ein neuer Wert zugewiesen wird?

Bitte korrigieren Sie mich, wenn ich hier falsch liege.

+0

Warum sind Sie die Zuordnung std :: make_unique (10) ptrA, dann eine Zeile später std :: make_unique (20) wenn du einfach * ptrA = 20 - oder noch kürzer machen kannst: mach einfach ptrA = std :: make_unique (20) und fertig damit? Oder geben Sie der Frage etwas mehr Kontext? – stijn

+3

@stijn, weil dieser Code nur die Idee, nicht den echten Code erklärt. – Slava

+0

@stijn, wenn man bedenkt, dass wir einen Zuweisungsoperator schreiben, ist einer der Mitglieder unique_ptr. – q0987

Antwort

4

zuerst nullptr Zuordnung ist superflous sowie irreführend, nur tun:

ptrA = std::make_unique<int>(20); 

ausreichend ist, da vor der Zuweisung der unique_ptr::operator= den unternehmenseigenen Speicher freigeben wird, bevor seine neue zu erwerben.

+0

Wenn Sie 'std :: make_unique' aufrufen, kann es sinnvoll sein, die Zuweisung auf diese Weise zu verwenden. Obwohl ich denke, die Unterscheidung ist wichtiger für 'std :: make_shared'. Wenn Sie einem Zeiger zuweisen, sind Sie jedoch vollkommen korrekt. – Guvante

+0

@ 101010 Was ist das potenzielle Problem, wenn wir stattdessen Case I verwenden. – q0987

+0

@ q0987: Sie erstellen ein zusätzliches temporäres, um das Ergebnis des 'std :: make_unique'-Aufrufs potentiell zu halten (es wird dann in' ptrA' verschoben, so dass es möglicherweise entfernt wird, aber keine Garantie). – Guvante

7

Die Zuweisung von nullptr vor dem Zuweisen eines neuen Werts ist sinnlos.

+4

Schlechter als sinnlos - es reduziert das Signal-Rausch-Verhältnis und ist daher schädlich. – SergeyA

1

Ich dachte, das Aufrufen von Reset oder das Zuweisen von nullptr wäre sinnlos gewesen, aber es stellt sich heraus, dass dies einen kleineren Footprint im Assembler verursacht. Das Compiler-Explorer auf https://godbolt.org/ mit gcc 7.2 und mit O3 dem Code:

void test1() 
{ 
    auto test1 = std::make_unique<int>(5); 
    test1 = std::make_unique<int>(6); 
} 

Überraschenderweise verursacht mehr Anweisungen als die hässliche Version:

void test2() 
{ 
    auto test1 = std::make_unique<int>(5); 
    test1 = nullptr; 
    test1 = std::make_unique<int>(6); 
} 
Verwandte Themen