2009-04-13 4 views

Antwort

12

Ja, aber das üblichere C++ - Idiom für diese Situation ist die Verwendung einer Referenz (und wahrscheinlich einer Konstantenreferenz) anstelle eines Zeigers. Also statt

void foo(sometype * p) { 
    p->func(); 
} 

Sie schreiben:

void foo(sometype & p) { 
    p.func(); 
} 

Dies hat den Vorteil, dass Sie brauchen nicht zu dereferenzieren das Objekt in der Anrufer:

void afunc() { 
    sometype t; 
    foo(t); 
} 

und gibt auch eine unterschwellige Hinweis für den Leser, dass Sie nicht beabsichtigen, dass die Funktion das Eigentum an dem Objekt übernimmt.

+3

"und wahrscheinlich eine const-Referenz": const & s sind großartig und sollten wann immer möglich verwendet werden, aber wann immer eine Funktion beabsichtigt, den Wert eines Parameters zu ändern, sollten Sie einen Zeiger und keine Referenz übergeben, damit Sie Änderungen vornehmen können der Parameter. Mem Besitz sollte gut dokumentiert sein – Tom

+0

+1 für Toms Antwort –

10

Wenn Sie sicher sind, dass der Aufruf synchron ist, ist es absolut zulässig, die Adresse des Stack-zugewiesenen Objekts an die Funktion zu senden. Wenn der Aufruf asynchron ist (d. H. Die von Ihnen aufgerufene Funktion übergibt den Zeiger an einen anderen Thread), entstehen Probleme, da Sie möglicherweise versuchen, auf die Speicheradresse des anderen Threads zuzugreifen, selbst nachdem das zugeordnete Stapelobjekt gelöscht wurde.

+0

Ganz hypothetisch aber, wie mit einfachen C oder C++ Sprache konstruieren man keine Funktion asynchron aufrufen können. Assafs Antwort ist viel näher an das tägliche Leben. – lothar

+0

Lothar - wie wäre es mit Gabel()? Jedes nicht-triviale Programm, das immer noch in einem einzigen Thread läuft, ist ein Dinosaurier. Modding dies. – MaxVT

+0

@MaxVT Calling Fork ist in keiner Weise eine Methode zum asynchronen Aufruf einer Funktion, Ihr gesamter Prozess wird dupliziert (einschließlich aller Daten). – lothar

6

Solange die empfangende Funktion nicht davon ausgeht, dass sie das Eigentum an der Ressource erhält (und versucht, sie freizugeben), sicher. Eine Referenz könnte jedoch eine bessere Idee sein.

2

Es ist völlig in Ordnung für einen synchronen Funktionsaufruf. Wenn der Aufruf asynchron ist, kann dies zum Absturz führen, wenn das Stapelobjekt gelöscht wird, wenn es den Gültigkeitsbereich verlässt.

2

Sie sollten darauf achten, diesen Zeiger nicht für die weitere Verwendung zu speichern. Zum Beispiel:

void store(int* param) { 
    // Store pointer in some global storage for further use 
    global_storage.add_param(param); 
} 
void func() { 
    int test_var = 5; 
    store(&test_var); // Pass the pointer to the global storage 
} 
// At this point stack object test_var will be destroyed 
// Global storage contains a pointer, that points to some garbage 
1

Es ist sicherlich gültig, aber mit vielen Vorbehalten. Hier sind die Top Dinge im Auge zu behalten (einige bereits von anderen erwähnt, andere nicht.)

  • Der Zeiger selbst bedeuten kann, dass die Ressource Eigentum zu übergeben wird die angerufene (dh sie muss es frei nach dem Gebrauch) . Hier ist eine Referenz vorhanden.
  • In vielen Situationen ist die Funktion, die Sie aufrufen müssen, bereits definiert und Sie können sie nicht ändern. Sie müssen ihr Verhalten studieren und sicherstellen, dass sie nicht das Objekt besitzt, es statisch speichert oder es an anderer Stelle kopiert.
  • Wenn die Funktion, die Sie aufrufen, einen Nullzeiger verwenden muss, um die Abwesenheit dieses Parameters anzuzeigen, haben Sie keine Wahl, eine Referenz zu verwenden.
  • Asynchrone Aufrufe sind absolut no-no (es sei denn natürlich, Sie blockieren, bis sie mit Ihrem lokalen Objekt fertig sind und dann zurückkehren).
  • Die aufgerufene Funktion sollte auf keinen Fall jemals über die Größe des betreffenden Objekts hinausgehen, dies wird Ihren Stack zerstören und fast sicher Ihr Programm zum Absturz bringen!
  • Das Aufrufen einer Funktion, die für den Zugriff auf Bytes außerhalb der Größe des Objekts anfällig ist, kann eine Sicherheitslücke darstellen. In der Tat ist dies die gebräuchlichste Methode, um in sichere Systeme einzudringen. Dies wird Pufferüberlauf genannt.(Über den Rahmen Ihrer Frage, aber Sie können mehr here und here lesen)