2017-11-25 2 views
3

Ist die folgende Wrapper-Klasse einer „OK“ Art und Weise ein Zwischenobjekt mit std::unique_ptr zu halten, ohne das Kopieren me das me Mitglied zugreifen?Wenn rvalue Destruktor aufgerufen/ist dies ok

Hier ist das Beispiel

#include <iostream> 
#include <memory> 

/* myobj from another library */ 
class myobj { 
public: 
    std::string me; /* actual member of interest is larger and more 
         complicated. Don't want to copy of me or myobj */ 

    /* more members in actual class */ 

    myobj(std::string i_am) { 
     /* more stuff happens in constructor */ 
     me = i_am; 
    } 

    ~myobj(){ 
     std::cout << me << ": Goodbye" << std::endl; 
    } 
}; 

/* A function in another library */ 
void who_is_this(std::string *who){ 
    std::cout << "This is " << *who << std::endl; 
} 

/* wrapper which I define */ 
class myobj_wrapper { 
    using obj_ptr = std::unique_ptr<myobj>; 
    obj_ptr ptr; 

public: 
    std::string *who; 

    myobj_wrapper(std::string i_am): 
     ptr(new myobj(i_am)), who(&ptr.get()->me) {} 

    myobj_wrapper(myobj &the_obj): who(&the_obj.me) { } 
}; 

int main() 
{ 
    { 
     myobj bob("Bob"); 
     who_is_this(myobj_wrapper(bob).who); 
    } 

    who_is_this(myobj_wrapper("Alice").who); 

    return 0; 
} 

Die resultierenden Ausbeuten Programm

This is Bob 
Bob: Goodbye 
This is Alice 
Alice: Goodbye 

I myobj_wrapper für mehr Objekte definieren die who Zeiger zu erhalten. Was ich bin unsicher, ob das Objekt von Interesse (std::string im oben genannten) zerstört wird, bevor es in der who_is_this Funktion ausgewertet wird. Es scheint nicht von oben, aber sollte ich das erwarten? Gibt es Fallen mit der obigen Lösung?

+0

der Code Es sieht OK aus, obwohl ich zugeben muss, dass ich den Punkt der Übung nicht ganz verstehe. Ich verstehe das Problem nicht, das ist angeblich eine Lösung auf zu. –

+0

Was meinst du mit ** rvalue destructor **? –

+0

Ich meine das dynamisch zugewiesene Objekt an 'who_is_this (myobj_wrapper (" Alice "). Who);' –

Antwort

1

Ich bin nicht sicher, aber hier ist meine Sicht:

who_is_this(myobj_wrapper("Alice").who); 

Dies wird ein Wrapper-Objekt erstellen, das die Stringliteral als Argument nehmen. Dann wird eine myobj Instanz dynamisch erstellt und einem eindeutigen Zeiger übergeben. Über diese Instanz erhalten wir ihre Daten (die Zeichenfolge) und stellen einen traditionellen Zeiger vom Wrapper-Klassenpunkt auf sie. So, jetzt zeigt who auf me, d. H. Alice.

Wir passieren who (das ist ein Zeiger) auf:

void who_is_this(std::string *who) 

was bedeutet, dass die Parameter der Funktion who ist nicht eine Kopie, weist jedoch auf die Originaldaten.

Also jetzt die ganze Frage ist, wenn das Wrapper-Objekt außerhalb des Geltungsbereichs gehen wird (daher wird sein Datenelement (der eindeutige Zeiger) auch außerhalb des Bereichs gehen, was bedeutet, dass die myobj Instanz, die dynamisch erstellt wurde, wird Garbage Collected bedeutet die abwechselnd dass me zu den Gültigkeitsbereich verlassen wird, und so wird who.

Die Wrapper-Objekt den Gültigkeitsbereich verlassen wird, nachdem who_is_this() ausgeführt wird, was bedeutet, dass der Code in Ordnung ist.

+0

"_Das Wrapper-Objekt wird den Geltungsbereich verlassen, ** nachdem **' who_is_this() 'ausgeführt wird, was bedeutet, dass Ihre Code ist OK_ "Cool, danke für die Antwort! –

+1

Thx. Ich nahm an, dass jemand einen Kommentar über eine Fallstricke hinzufügen könnte. Ich denke, es gibt keine. Das konkrete Beispiel ist [hier] (https://github.com/boennecd/dynamichazard/blob/master/src/problem_data.h), wo ich die Armadillo-Bibliothek benutze. Siehe die Klasse "map_res" und z. B. die "lp_map" -Methoden. Manchmal wird ein neues 'arma :: vec' benötigt, während zu anderen Zeiten kein neues Objekt erstellt werden muss. (Ignorieren Sie den Kommentar über der Klasse - es ist falsch). –