2010-04-26 5 views
17

Gibt es ein Lager no-op deallocator in-Boost mit boost::shared_ptr für statische Objekte zu verwenden, usw.No-op deallocator für boost :: shared_ptr

Ich weiß, es ist ultra-trivial zu schreiben, aber ich weiß nicht Ich möchte meinen Code mit extra kleinen Funktionen versehen, wenn bereits eine vorhanden ist.

+4

Wenn das Objekt nicht zerstört werden muss, warum steckst du es dann in ein shared_ptr? –

+5

Sehr praktisch, wenn Sie überall mit intelligenten Zeigern über Bord gegangen sind und Sie eine Stapel- oder Elementvariable an eine Funktion übergeben möchten, die 'shared_ptr' erfordert. –

+1

@Mark Ransom: Sie lassen mich an Codebasen denken, die mich zum Weinen bringen. : P –

Antwort

10

Ja gibt es einen hier:

#include <boost/serialization/shared_ptr.hpp> // for null_deleter 

class Foo 
{ 
    int x; 
}; 

Foo foo; 
boost::shared_ptr<Foo> sharedfoo(&foo, boost::serialization::null_deleter()); 

Es ist natürlich die Gefahr, mit der Tatsache, dass Sie die Funktion, die Sie aufrufen wissen müssen die shared_ptr für die spätere Verwendung nicht speichern, da es tatsächlich geht gegen die Politik von shared_ptr, indem das zugrunde liegende Objekt bis zu der letzten Instanz von shared_ptr gültig bleibt.

+0

Sieht aus wie das ist so nah wie es nur geht. –

1

Wäre es nicht sauberer, nur eine zusätzliche Referenz zu nehmen, damit der Entscheider niemals aufgerufen wird? (Obwohl das immer noch nicht sehr sauber ist.)

Ich kann nicht sagen, dass es keine Funktion in Boost gibt, die den Job machen würde, aber es klingt nicht wie etwas, das sie aufnehmen möchten.

EDIT: die Kommentare gelesen und ein wenig Dokumentation, läuft es auf diese nach unten:

  1. Referenz undicht. An einem bestimmten Punkt, führen Sie dies aus:

    new shared_ptr(my_global_shared_ptr); 
    

    Vorteile: konzeptionell einfach. Nachteile: Sie verlieren etwas auf dem Haufen.

  2. Benutzerdefinierte Freigabe. Da shared_ptr wenig von der Deallocator-Funktion benötigt, würde eine anonyme Identitätsfunktion, wie sie in der anderen Antwort bereitgestellt wird, gut funktionieren.

    Vorteile: Hebelwirkung Boost und hat absolut keinen Overhead. Nachteile: erfordert ein wenig Dokumentation.

  3. Nicht statisches globales Objekt. Wenn es ein globales shared_ptr für Ihr Objekt gibt, sollte das die einzige Möglichkeit sein, darauf zuzugreifen. Ersetzen Sie die Deklaration des Globalen durch shared_ptr initialisiert durch new my_class. Ich denke, das ist das Beste.

+0

Wie würden Sie eine zusätzliche Referenz nehmen? Ich dachte nicht, 'shared_ptr's Anzahl war zugänglich. –

+0

@Mark Ransom: Ich denke, er meint kopieren Sie die 'shared_ptr' und speichern Sie es irgendwo. –

+0

Ja, aber diese zusätzliche Kopie wird irgendwann zerstört werden. Scheint nicht sehr praktisch. –

3

Solution verwendet Boost.Lambda:

#include <boost/shared_ptr.hpp> 
#include <boost/lambda/lambda.hpp> 

int main() 
{ 
    int *p = new int(5); 

    { 
     boost::shared_ptr<int> sp(p, boost::lambda::_1); 
    } 

    delete p; 
} 

'boost :: lambda :: _ 1' erzeugt ein leeres Funktors, die ein Argument.

Sie werden wahrscheinlich einen // Kommentar einfügen, um die Leute wissen zu lassen, warum Sie es getan haben.

+1

Das würde in die Kategorie "Ich möchte nicht meinen Code streuen" * fallen. –

+0

Diese Lösung beinhaltet mehr Beregnung als die Verwendung eines hypothetischen boost :: no_op_deallocator() anstelle von boost :: lambda :: _ 1? – scjohnno

+2

Eine sehr clevere Lösung, aber ich denke, ich hätte lieber die triviale Funktion irgendwo und gebe ihr einen beschreibenden Namen. –

0

FWIW, das was ich benutze. Ich verwende es in Komponententests, um ein lokales in ein shared_ptr anzupassen.

// The class NoOp_sptr_Deleter can be used to construct a shared_ptr<>() 
// that will NOT delete the pointee. 
// This can be helpful in unit-testing. Wrapping a local as a shared_ptr. 
// Do take care with the lifetimes though. 
struct NoOp_sptr_Deleter 
{ 
    void operator()(void const *) const {} 
}; 

template<typename T> 
boost::shared_ptr<T> FakeSharedPtrFromRef(T& aRef) 
{ 
    return boost::shared_ptr<T>(&aRef, NoOp_sptr_Deleter()); 
} 
+0

Das OP hat gezielt nach Lösungen gefragt, die bereits von Boost oder der stdlib bereitgestellt werden. Er weiß *, dass es extrem trivial ist, eine solche Funktion/Funktion zu schreiben. – Xeo

Verwandte Themen