std :: unique_ptr und pointer-to-pointer

8

Ich habe std :: unique_ptr verwendet, um einige COM-Ressourcen zu speichern, und habe eine benutzerdefinierte Löschfunktion bereitgestellt. Viele der COM-Funktionen möchten jedoch Zeiger auf Zeiger. Im Moment verwende ich das Implementierungsdetail von _Myptr in meinem Compiler. Wird es unique_ptr brechen, um direkt auf dieses Datenelement zuzugreifen, oder sollte ich einen gajillion temporären Zeiger speichern, um unique_ptr rvalues ​​aus?

zu konstruieren     
Puppy 19.12.2010, 20:36
quelle

4 Antworten

6

COM-Objekte sind von ihrer Art nach zählbar. Daher sollten Sie keine intelligenten Smart Pointer wie z. B. ATL::CComPtr oder _com_ptr_t verwenden, auch wenn dies für Ihren Anwendungsfall nicht geeignet erscheint denke nur, dass du ihnen zu viel Gewicht zuordnest). Beide Klassen sind so konzipiert, dass sie in allen gültigen Szenarien verwendet werden können, die bei der Verwendung von COM-Objekten auftreten, einschließlich des Erhalts des Pointer-to-Pointer. Ja, das ist ein bisschen zu viel Funktionalität, aber wenn Sie keine spezifischen negativen Konsequenzen erwarten, die Sie nicht tolerieren können, sollten Sie nur diese Klassen verwenden - sie sind genau für diesen Zweck entworfen.

    
sharptooth 17.02.2011, 15:07
quelle
4

Ich habe das Problem vor nicht allzu langer Zeit lösen müssen und habe zwei verschiedene Lösungen gefunden:

Der erste war ein einfacher Wrapper, der einen 'schreibbaren' Zeiger verkapselt hat und könnte std::move d in meinen Smart Pointer sein. Dies ist nur ein wenig praktischer als die von Ihnen erwähnten Temp-Zeiger, da Sie den Typ nicht direkt auf der Call-Site definieren können.

Deshalb bin ich nicht dabei geblieben. Also, was ich getan habe, war eine Retrieve Helfer-Funktion, die die COM-Funktion erhalten und meinen Smart-Pointer zurückgeben würde (und den gesamten internen Inhalt des temporären Pointers erledigen würde). Nun funktioniert das trivial mit freien Funktionen, die nur einen einzigen T** -Parameter haben. Wenn Sie dies auf etwas komplexeren verwenden möchten, können Sie den Aufruf einfach über std::bind übergeben und nur den zurückzugebenden Zeiger frei lassen.

Ich weiß, dass dies nicht direkt das ist, was Sie fragen, aber ich denke, es ist eine saubere Lösung für das Problem, das Sie haben.

Als Randnotiz würde ich Boost's intrusive_ptr anstelle von std :: unique_ptr vorziehen, aber das ist wie immer Geschmackssache.

Bearbeiten: Hier ist ein Beispielcode, der von meiner Version mit boost :: intrusive_ptr übertragen wurde (so dass es nicht sofort mit unique_ptr funktioniert)

%Vor%

Zum Beispiel kann es so verwendet werden:

%Vor%

Bei Bonuspunkten können Sie retrieve sogar das unique_ptr zurückgeben, anstatt es als Referenz zu verwenden. Der Funktor, den bind generiert, sollte eine Signatur typedefs haben, um den Zeigertyp abzuleiten. Sie können dann eine Ausnahme auslösen, wenn Sie eine schlechte HRESULT erhalten.

    
ltjax 03.03.2011 18:59
quelle
1

C ++ 0x Smartpointer haben eine portable Möglichkeit, den rohen Pointercontainer .get () zu erhalten oder es komplett mit .release () freizugeben. Sie können auch immer & amp; (* ptr) verwenden, aber das ist weniger idiomatisch.

Wenn Sie Smart Pointer verwenden möchten, um die Lebensdauer eines Objekts zu verwalten, aber rohe Pointer benötigen, um eine Bibliothek zu verwenden, die keine Smartpointer (einschließlich der Standard-c-Bibliothek) unterstützt, können Sie diese Funktionen am einfachsten nutzen die rohen Zeiger.

Denken Sie daran, dass Sie den Smart Pointer für die Dauer, in der das Objekt leben soll, immer noch behalten müssen (achten Sie also auf seine Lebensdauer).

Etwas wie:

%Vor%

Hinweis: Dies ist nur eine allgemeine Antwort auf Ihre Frage. Wie man COM am besten benutzt, ist ein getrenntes Problem, und es kann sehr gut sein, dass chouttooth korrekt ist.

    
mmocny 03.03.2011 18:41
quelle
-1

Verwenden Sie eine Hilfsfunktion wie diese.

%Vor%

Überprüfen Sie die Implementierung

%Vor%     
Alexander Drichel 25.03.2013 12:23
quelle

Tags und Links