2010-08-26 8 views
6

Qu'en est-il de l'appel de shared_from_this pour les objets alloués à la pile? enable_shared_from_this dans la liste des classes de base est un indicateur pour l'utilisateur de la classe dérivée pour créer c'est seulement sur le tas (et nous espérons juste pour l'utilisation correcte de classe) ou nous pouvons avoir une protection plus forte contre de telles erreurs? Ou je ne comprends pas certains moments?

code Exemple: enable_shared_from_this et les objets sur la pile

 
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

Que demandez-vous exactement? Voulez-vous savoir s'il existe un moyen d'empêcher l'appel 'shared_from_this()' sur les objets alloués à la pile? –

Répondre

10

Donc, pour protéger contre ce problème, vous pouvez faire vos contstructors privé et seulement fournir des fonctions de création qui renvoient shared_ptr - cette façon, l'objet ne peut pas être attribué sur la pile, comme ceci:

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 
} 

Si vous vous souhaitant anoperator = vous pouvez trouver fournir une fonction de clone à l'aide d'un constructeur de copie privée mis en œuvre, quelque chose comme ça

// 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

Je suis conscient que vous pouvez probablement toujours les allouer sur la pile si vous êtes prêt à sauter à travers des cerceaux pour être intentionnellement mal .. mais à mon humble avis, cela protège de la plupart des erreurs innocentes. –

+0

Donc, nous allons d'abord concevoir des classes de tas seulement ... Cette approche est-elle largement utilisée? – cybevnm

+0

Pourquoi avez-vous besoin de désactiver l'opérateur d'affectation? Normalement, il est bon d'assigner des objets contenus dans shared_ptr. Il serait traité de la même manière que toute autre assignation entre deux objets * existants * - les comptages de référence ne seraient pas affectés. Les deux objets * different * auraient juste le même contenu après l'assignation. – nobar