Frage

Referenzen in C ++ ein conveneint Konstrukt sind, die uns erlauben, die folgende C-Code zu vereinfachen:

f(object *p){
  //do something
}

int main(){
  object* p = (object*) calloc(sizeof(object));
  f(p);
}

f(object& o){
  //do something
}

int main(){
  object o = object();
  f(o);
}

Gemeinschafts-Zeiger sind eine weitere Bequemlichkeit in C ++, die Speicherverwaltung zu vereinfachen. Aber ich bin nicht sicher, wie eine shared_ptr auf eine Funktion wie f(object& o) passiert, die Argumente als Verweis übernimmt?

f(object& o){
  //do something
}

int main(){
  shared_ptr<object> p (new object());
  f(*p);
}

Wird der gemeinsame Zeiger erhöht werden, wenn die Aufgabe, unter Bezugnahme auf eine Funktion übergeben wird?

War es hilfreich?

Lösung

Nehmen Sie einen shared_ptr nach Wert, und der Referenzzähler erhöhen. Dies ist einfacher, wenn Sie typedef es:

typedef boost:shared_ptr<object> object_ptr;

void foo(object_ptr obj)
{
    obj->/* stuff*/;
    obj.reset(); //only resets this local copy, that means:
                 // reduce reference count (back to 1), and
                 // set obj to point at null.
}

int main(void)
{
    object_ptr obj(new object());
    foo(obj);
}

Beachten Sie Referenzen sind Aliase. Wenn Sie über einen Verweis, bist du nicht vorbei Zeiger, Kopien, etc ..., sind Sie ein anderes Objekt Aliasing. (In Wirklichkeit sind sie als Zeiger implementiert):

typedef boost:shared_ptr<object> object_ptr;

void foo(object_ptr& obj)
{
    obj.reset(); // the references was never increased, since a copy has not
                 // been made, this *is* obj in main. so the reference 
                 // goes to 0, and obj is deleted
}

int main(void)
{
    object_ptr obj(new object);
    foo(obj); // after this, obj has been reset!
}

Denken Sie immer daran, korrekt sein const, zu verhindern Fehler:

typedef boost:shared_ptr<object> object_ptr;

void foo(const object_ptr& obj)
{
    obj.reset(); // cannot do! 
}

int main(void)
{
    object_ptr obj(new object);
    foo(obj);
}

Ich denke, Sie sollten lieber intelligente Zeiger als Verweise auf die passieren, wenn möglich, Fremd und -dekremente zu vermeiden (und Kopien und so weiter).

Andere Tipps

  

Wird der gemeinsame Zeiger erhöht werden, wenn die Aufgabe, unter Bezugnahme auf eine Funktion übergeben wird?

Nein, wie Sie den Rohzeiger zugreifen und es dann vorbei. Sie wollen etwas, ähnlich wie dies tun:

f(shared_ptr<object> o){
  //do something
}

int main(){
  shared_ptr<object> p (new object());
  f(p);
}
f(object& o){
  //do something
}

int main(){
  shared_ptr<object> p (new object());
  f(*p);
}
     

Wird der gemeinsame Zeiger erhöht   wenn seine Aufgabe wird durch Referenz übergeben   auf eine Funktion?

In dem obigen Code - Nr. p wird seinen Referenzzähler gleich 1 zu allen Zeiten. Sie können dies in einem Debugger überprüfen. Shared_ptr des Referenzzähler zählt die Anzahl der shared_ptr-Instanzen, die auf das gleiche Objekt zeigen, ist es nicht Referenzen verfolgen Sie durch den Aufruf von operator * erstellen (). Und es muss nicht - da p ist garantiert bis zum Ende des Umfangs und der Funktionsaufruf zu leben, ist im selben Umfang (oder tiefer) p wird dort während des gesamten Anrufs auf f (). Also alles in Ordnung ist.

... es sei denn, in f Sie nehmen die Adresse o und irgendwo gespeichert werden, die nach der dauern wird f kehrt zurück. Diese Sie mit allen Mitteln vermeiden sollte -. Übergeben Sie die shared_ptr, wenn Sie das tun müssen,

Das Wichtigste zuerst, von einer Funktionalität Sicht Referenzen in C ++ sind genau die gleiche wie Zeiger. Sie einzige Grund, warum sie in die Sprache hinzugefügt wurden, war die Syntax der Betreiber Überlastung zu machen natürlicher sein. (Zum Beispiel, damit man ein + b statt & a + b & schreiben)

Ihre C und C ++ Code-Beispiele sind absolut nicht gleichwertig. Die C-Version von C ++ Code wäre:

f(object *p){
  //do something
}

int main(){
  object o;
  object_constructor(&o);
  f(&o);
  object_destructor(&o);
}

In der Tat, dies ist die Art von Code, der Ihre C ++ Compiler konzeptionell generieren wird.

Mit Bezug auf Ihre zweite Frage: Ja, das ist der richtige Weg, um die Funktion f zu nennen. Der freigegebene Zeigerzähler wird nicht erhöht werden. Der eigentliche Zeiger auf das Objekt wird übergeben, als ob Sie nicht ein shared_ptr verwendet haben. Es ist jedoch sicher, solange f nicht ist flippig etwas zu tun. Denken Sie daran, dass die gleiche Sache genau geschieht, als ob f der Parameter einen Zeiger anstelle eines Verweises nahm. Der einzige Unterschied ist, dass die Compiler automatisch die Adresse der Variablen verstreicht, ohne dass Sie explizit mit, um den Operator & verwenden.

Ich persönlich mag es nicht immer Variablen durch Verweis übergeben (durch konstante Referenz vorbei ist ok obwohl). Ich ziehe einen Zeiger stattdessen zu verwenden, da sie es klarer an der Aufrufstelle machen, dass die Funktion, die wir nennen es kann möglicherweise Argument ändern ist (da die & Symbol ist an der Aufrufstelle sichtbar).

Frieden

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top