Referenzzählung in C ++ OO-Style

8

Ich kam über eine faszinierende Implementierung einer Basisklasse auf die C ++ FAQ < Dies könnte nach meinem naiven Verständnis als eine Alternative zu einigen der Smart-Pointer-Implementierungen (zB shared_ptr) dienen. Hier ist der Beispielcode wörtlich, aber bitte folgen Sie dem obigen Link für eine Erklärung:

%Vor%

Ich sehe diesen Ansatz nicht in C ++ - Bibliotheken; obwohl es ziemlich elegant scheint. Unter der Annahme einer single-threaded Umgebung, der Einfachheit halber, bitte beantworten Sie die folgenden Fragen:

  1. Ist dies eine geeignete Alternative zum Smart-Pointer-Ansatz, um die Lebensdauer von Objekten zu verwalten, oder ist es nur ein Problem?
  2. Wenn es geeignet ist, warum nehmen Sie an, dass es nicht öfter verwendet wird?
Verax 03.08.2012, 01:49
quelle

4 Antworten

4
  

Ist dies eine geeignete Alternative zum Smart-Pointer-Ansatz, um die Lebensdauer von Objekten zu verwalten, oder fragt es nur nach Ärger?

Nein, ich denke nicht, dass es eine gute Idee ist, die Referenzzählung neu zu erfinden, besonders da wir std :: shared_ptr jetzt in C ++ 11 haben. Sie können Ihre möglicherweise polymorphe Referenz-gezählte Pimpl-Idiom-Klasse einfach in Bezug auf std :: shared_ptr implementieren. Beachten Sie, dass wir nicht mehr copy ctor, assignment, dtor implementieren müssen und Mutation wird einfacher w.r.t. der Referenzzähler und das Klonen:

%Vor%

... und die Implementierung ...

%Vor%

(ungetestet)

  

Wenn es geeignet ist, warum nehmen Sie an, dass es nicht öfter verwendet wird?

Ich denke, Referenzzählung, wenn Sie es selbst implementieren, ist leichter falsch zu verstehen. Es hat auch den Ruf, in Multithread-Umgebungen langsam zu sein, da die Referenzzähler atomar inkrementiert und dekrementiert werden müssen. Aber ich denke, aufgrund von C ++ 11, das shared_ptr und move semantics anbietet, könnte dieses Copy-on-Write-Muster wieder etwas populärer werden. Wenn Sie die Bewegungssemantik für die Fred-Klasse aktivieren, können Sie einige der Kosten für das automatische Erhöhen der Referenzzähler vermeiden. Das Verschieben eines Fred-Objekts von einem Ort zu einem anderen sollte daher noch schneller sein als das Kopieren.

    
sellibitze 06.08.2012, 07:44
quelle
4
  

Ist dies eine geeignete Alternative zum Smart-Pointer-Ansatz, um die Lebensdauer von Objekten zu verwalten, oder fragt es nur nach Ärger?

Es ist eine Alternative, aber es sei denn, Sie haben einen sehr guten Grund, es zu benutzen, es ist nur das Rad neu zu erfinden (auf nicht wiederverwendbare Weise).

Wenn Sie Ihren Code so ändern, dass er stattdessen shared_ptr verwendet, müssen Sie die Semantik für Copy / Ownership explizit definieren (und den Copy-Konstruktor und die Zuweisung in Ihrer pimpl-Basis definieren). Sie werden auch Code verwenden, der bereits definiert und getestet wurde (da er Teil der Bibliothek ist).

  

Wenn es geeignet ist, warum nehmen Sie an, dass es nicht öfter verwendet wird?

Weil shared_ptr verfügbar ist und bereits die Funktionalität und alle "Gotcha" s implementiert.

    
utnapistim 07.08.2012 13:05
quelle
3

Ich auch, ich frage mich, ob es als Alternative für Smart Pointer geeignet ist.

Aber IMO, um ein intelligenter Zeiger zu sein, muss eine Klasse als ein Zeiger verwendbar sein, d. h .:

%Vor%

Also ja, es ist eine Art Speicherverwaltung, aber es ist kein intelligenter Zeiger, weil es nicht die Semantik eines Zeigers hat.

Wie in den Kommentaren erwähnt, ist das Pimpl-Idiom wirklich hilfreich, um die Kompatibilität aufrechtzuerhalten, und es kann auch die Entwicklung beschleunigen, da Sie die enthaltene Klasse nicht neu kompilieren müssen. ABER um den letzteren Vorteil zu haben, müssen Sie die innere Klasse (d. H. Daten) nicht innerhalb der Elternklasse definieren, sondern nur eine Vorwärtsdeklaration einfügen und die tatsächliche Definition in eine andere Überschrift einfügen.

%Vor%

Und ich finde es für die zukünftige Entwicklung nicht nützlich, die Variante von Data in der Klasse Fred zu deklarieren, denn wenn Sie eine andere Klasse hinzufügen müssen, müssen Sie Fred modifizieren, anstatt nur eine andere Klasse zu erstellen. Dies könnte gewollt sein, aber ich schlage vor, dass Sie diesen Teil vermeiden.

Wenn ich mir über etwas nicht sicher bin, kannst du gerne Fragen stellen!

    
fstamour 03.08.2012 02:49
quelle
3
  1. Die Antwort von C ++ - FAQ scheint eher ein einfaches Beispiel zu sein, wie man gemeinsam genutzte Daten verwaltet (mit Kopie beim Schreiben). Es fehlen einige Aspekte, die wichtig sein könnten.

  2. N / A mit meiner Meinung für 1.

Um den Overhead zu vermeiden, der mit der 'externen' Referenzzählung wie bei std::shared_ptr eingeführt wurde, können Sie einen intrusiven Ref-Zählmechanismus verwenden, wie in beschrieben Andrei Alexandrescus Buch Modernes C ++ Design . Die Klasse Loki :: COMRefCounted zeigt, wie eine solche Eigentumsrichtlinie für gemeinsame Windows-COM-Objekte implementiert wird.

>

Im Wesentlichen läuft es auf die Smart-Zeiger-Template-Klasse hinaus, die eine Schnittstelle akzeptiert, die die Referenzzählung und die Prüfung auf Verfügbarkeit von delete in der Pointe-Klasseninstanz selbst verwaltet. Ich weiß nicht, ob die STD C ++ - Bibliothek unterstützt, eine solche Richtlinienüberschreibung für die Klasse std::shared_ptr zu implementieren.

Wir verwenden die Loki-Bibliothek ausschließlich für das intelligente Zeigermodell in einem Anzahl der eingebetteten Projekte sehr erfolgreich. Vor allem wegen dieser Eigenschaft, um Feingranularitätsaspekte der Effizienz zu modellieren.

Beachten Sie, dass die vorgeschlagenen (eingebauten) Implementierungen standardmäßig nicht threadsicher sind.

Wenn all diese obigen Aspekte Ihren Zweck nicht betreffen, würde ich vorschlagen, für die einfache std::shared_ptr Repräsentation Ihrer Fred::Data Klasse zu gehen, wie in der Antwort von sellibitze gezeigt. Ich stimme auch mit den Punkten überein, die er im letzten Absatz aufstellt, Referenzzählung und intelligente Pointer-Semantik neigen dazu, dass sie falsch verstanden und falsch umgesetzt wird.

Wenn der C ++ 11-Standard oder Boost keine Optionen für Sie sind, bietet die loki-Bibliothek immer noch eine einfach zu integrierende und robuste Smart Pointer-Implementierung.

    
πάντα ῥεῖ 06.08.2012 18:44
quelle

Tags und Links