2010-08-26 9 views
6

Wie wäre es mit dem Aufruf von shared_from_this für stack allocated objects? enable_shared_from_this in der Liste der Basisklassen ist ein Indikator für den Benutzer der abgeleiteten Klasse für die Erstellung nur auf Heap (und wir hoffen nur auf korrekte Klassenbenutzung) oder können wir einen stärkeren Schutz gegen solche Fehler haben? Oder ich verstehe einige Momente nicht?

Beispielcode: enable_shared_from_this und Objekte auf dem Stack

 
class C : public enable_shared_from_this<C> 
{ 
public: 
    shared_ptr<C> method() { shared_from_this(); } 
};

void func() { C c; shared_ptr<C> ptr = c.method(); // exception comming from shared_from_this() }

+1

Wonach fragen Sie genau? Möchten Sie wissen, ob es eine Möglichkeit gibt, den Aufruf von 'shared_from_this()' auf Stack-allokierten Objekten zu verhindern? –

Antwort

10

So gegen dieses Problem schützen Sie Ihren contstructors privat machen können und nur Erstellungsfunktionen zur Verfügung stellen, die Shared_ptr zurückkehren - auf diese Weise kann das Objekt nicht auf dem Stapel, wie diese zugeordnet werden:

class C : public enable_shared_from_this<C> 
{ 
public: 
    static shared_ptr<C> create() { return shared_ptr<C>(new C()); } 
    shared_ptr<C> method() { shared_from_this(); } 

private: 
    C() {...} 

    // Make operator= and C(const C&) private unimplemented 
    // so the used cant do bad things like C c(* c_ptr); 
    C& operator=(const C &); 
    C(const C &); 
}; 


void func() 
{ 
    C c; // This doesnt compile 
    shared_ptr<C> ptr = c.method(); // So you can never get this 
} 

void altfunc() 
{ 
    shared_ptr<C> c_ptr = C::create(); 
    C & c_ref = *c; 
    shared_ptr<C> ptr = c_ref.method(); // OK 
} 

Wenn Sie sich für anoperator wollt finden = können Sie eine Klon-Funktion verfügen über eine eigene implementiert Kopie Konstruktor, so etwas wie diese

// This goes in class C 
shared_ptr<C> C::clone() const 
{ 
    return shared_ptr<C>(new C(*this)); 
} 

// This is how you can use it 
shared_ptr<C> c2 = c1->clone(); 
+0

Ich bin mir bewusst, dass Sie diese wahrscheinlich noch auf dem Stapel zuweisen können, wenn Sie bereit sind, durch einige Reifen zu springen, um absichtlich böse zu sein .. aber IMHO schützt dies vor den meisten unschuldigen Fehlern. –

+0

Also werden wir zuerst Heap-Only-Klassen entwerfen ... Wird dieser Ansatz weit verbreitet verwendet? – cybevnm

+0

Warum müssen Sie den Zuweisungsoperator deaktivieren? Es ist normalerweise in Ordnung, Objekten, die sich in shared_ptr befinden, Objekte zuzuordnen. Es würde genauso gehandhabt werden wie jede andere Zuweisung zwischen zwei * existierenden * Objekten - Referenzzählungen wären nicht betroffen. Die zwei * verschiedenen * Objekte hätten nach der Zuweisung nur den gleichen Inhalt. – nobar

Verwandte Themen