shared_ptr - Übergabe nach Wert vs nach Referenz

8

Angenommen, ich habe:

%Vor%

In einem Thread erstelle ich ein Event und sende es ab, um es zu versenden:

%Vor%

Das EventDispatcher empfängt ein EventPtr und fügt es einer Warteschlange hinzu, die in einem anderen Thread verarbeitet wird ... aber was ist eine geeignete Methodensignatur für die Dispatch-Methode?

%Vor%

oder

%Vor%

Beachten Sie, dass mein EventDispatcher eine Warteschlange hat:

%Vor%

Der andere Thread löscht später ein Ereignis aus der Warteschlange und übergibt es an etwas, um das Ereignis zu verarbeiten:

%Vor%

Was ist wiederum eine geeignete Methodensignatur für die Methode process ? Ich frage mich, ob ich das nackte Event* einfach an die Prozessmethode weitergeben kann?

Ich frage mich, ob ich den Wert einfach überschreiten soll, damit die Referenzzahl genau ist? Ich bin wirklich nur besorgt über die Tatsache, dass ein Thread auf die Warteschlange drängt und ein anderer Thread aus der Warteschlange platzt und ich nicht irgendwo Zeiger lecke ...

Danke!

    
Tim Reddy 16.03.2011, 19:36
quelle

3 Antworten

4
  

Der EventDispatcher empfängt ein EventPtr und fügt es zu einer Warteschlange hinzu, die in einem anderen Thread verarbeitet wird ... aber was ist eine geeignete Methodensignatur für die Dispatch-Methode?

Jeder Vorschlag ist gut; Die Übergabe von const-Verweis ist wahrscheinlich effizienter, da der Referenzzähler des Zeigers nicht geändert werden muss. In beiden Fällen fügt push_back eine Kopie des Zeigers in die Warteschlange ein und hält das Ereignis in der Warteschlange aktiv.

  

Was ist wiederum eine geeignete Methodensignatur für die Prozessmethode? Ich frage mich, ob ich das nackte Event * einfach an die Prozessmethode weitergeben kann?

Wenn Sie den geteilten Zeiger (nach Wert oder Verweis) übergeben, wird die Eigentümerschaft des Ereignisses eindeutig dokumentiert und durchgesetzt, und der Prozessor kann es nach dem Aufruf von process() bei Bedarf behalten. Das Übergeben eines rohen Zeigers bringt Unsicherheit in das Eigentum; Der Bearbeiter benötigt einen Vertrag, der besagt, dass er das Ereignis nicht übernimmt und nicht versuchen muss, darauf zuzugreifen, sobald process() beendet ist.

    
Mike Seymour 16.03.2011, 19:47
quelle
1

Im großen Ganzen spielt es keine Rolle, ob Sie nach Wert oder nach Referenz vorgehen. In beiden Fällen wird die Referenzzahl erhöht, wenn Sie shared_ptr kopieren, um sie in die Warteschlange zu schieben.

Das Übergeben des leeren Zeigers ist auch in Ordnung, solange Sie vorsichtig sind, dass Sie nicht mit zwei verschiedenen shared_ptr Instanzen mit unterschiedlichen Referenzzählungen, eine im Aufrufer und eine im Aufrufer, enden.

Ich persönlich mag die "pass-by-value" -Option, weil es sich eher anfühlt, als würde man einen echten Zeiger passieren lassen. Das Anfordern eines shared_ptr als Argument erinnert die Programmierer, die die Funktion aufrufen, dass die Lebensdauer des Objekts den Funktionsaufruf überschreiten soll und dass der Aufrufer das Argument in einem shared_ptr speichern möchte, falls die Funktion früh zurückkehrt wenn eine Ausnahme ausgelöst wird, usw.

    
Nick Meyer 16.03.2011 19:51
quelle
0

Beide Versandfunktionen funktionieren ordnungsgemäß.

Im ersten Fall wird eine Instanz des gemeinsamen Zeigers auf den Stapel kopiert und dann beim Hinzufügen zur Ereigniswarteschlange erneut kopiert. Dies bedeutet Kopieren des Zeigers und Erhöhen des Referenzzählers.

%Vor%

Im zweiten Fall wird nur ein Verweis auf eine existierende Instanz an die Funktion übergeben und dann in die Warteschlange kopiert. Ich würde diese Variante verwenden.

%Vor%

Wenn Sie den geteilten Zeiger an process () übergeben, können Sie ihn auch als Referenz übergeben:

%Vor%     
matejk 16.03.2011 19:59
quelle

Tags und Links