2016-03-22 4 views
0
Obj *obj = new Obj(); 
obj->destroy(); 
if (obj == NULL) 
    cout << "yes"; 

Wie schreibe ich die Methode "destroy()", um "ja" auszugeben?Wie kann ein Zeiger selbst NULL machen?

+6

Kurz gesagt: Sie können nicht. –

+2

Machen Sie es sich nicht schwer ... 'void Obj :: destroy() {cout <<" yes "; } ':) –

+0

^^ lol, während streng korrekt, ich vermute, das ist nicht das, was das OP eigentlich wollte :) –

Antwort

3

unmöglich, weil obj eine lokale Variable ist. destroy() hat keinen Zugriff auf lokale Variablen am Aufrufstandort.

Was Sie fragen, ist so unmöglich, wie dies:

void f() 
{ 
    // set main's i to some other value? --> impossible 
} 

int main() 
{ 
    int i = 0; 
    f(); 
    if (i == 1) { 
     // ... 
    } 
} 

Wie für Ihr Beispiel die this Zeiger, der innerhalb destroy() zugegriffen werden kann, nicht verweisen auf die dynamisch zugewiesenen Obj Objekt, aber wie soll wissen, über andere Zeiger auf das gleiche Objekt Obj? Es kann nicht. So funktioniert die Sprache.

Technisch natürlich können Sie nur einen Verweis auf die lokale Variable übergeben:

#include <iostream> 

struct Obj 
{ 
    void destroy(Obj*& ptr) 
    { 
     ptr = nullptr; 
    } 
}; 

int main() 
{ 
    Obj *obj = new Obj(); 
    obj->destroy(obj); 
    if (obj == nullptr) 
     std::cout << "yes"; 
} 

Praktisch aber dies macht keinen Sinn überhaupt und ist nicht idiomatischen in C++. Es gibt ein grundlegendes Problem, das Sie versuchen zu lösen. Sie möchten wahrscheinlich sicherstellen, dass destroy() nicht für Nullzeiger aufgerufen wird oder dass Zeiger auf zerstörte Objekte nicht mehr verwendet werden. Dieses Ziel ist richtig, aber deine Strategie ist falsch. Schauen Sie sich std::unique_ptr für einen ganz anderen Ansatz an.

1

Sie können nicht. Das Objekt steuert sich selbst, aber es steuert nicht die darauf zeigenden Zeiger. Es ist sich nicht einmal der Zeiger bewusst, die darauf zeigen (es könnte viele geben).

Sie könnten den umgekehrten Weg nehmen, obwohl durch eine unique_ptr oder Shared_ptr verwenden, wie folgt aus:

  • Statt in destroy() "Teardown" Logik des Habens, steckte es in die destructor von Object.
  • Verwenden Sie einen std::unique_ptr anstelle eines Standardzeigers.

Dann beenden Sie mit so etwas wie dies oben:

std::unique_ptr<Obj> ptr(new Obj()); 
// ... do things with ptr ... 
ptr.reset(nullptr); // Does teardown automatically and sets ptr to null