2010-08-26 8 views
6

¿Qué pasa con la llamada shared_from_this para apilar objetos asignados? enable_shared_from_this en la lista de las clases base es un indicador para el usuario de la clase derivada para crearlo solo en el montón (y solo esperamos el uso correcto de la clase) o podemos tener una protección más fuerte contra tales errores. O no entiendo algunos momentos? código

Ejemplo: enable_shared_from_this y objetos en la pila

 
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

¿Qué estás preguntando exactamente? ¿Desea saber si hay una forma de evitar llamar a 'shared_from_this()' en objetos asignados a la pila? –

Respuesta

10

Así que para proteger contra este problema, puede hacer que sus contstructors privado y sólo proporcionan funciones de creación que devuelven shared_ptr - de esta manera el objeto no puede ser asignado en la pila, así:

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 usted se encuentra deseando anoperator = se puede proporcionar una función de clonación usando un constructor de copia privada en práctica, algo como esto

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

Soy consciente de que probablemente aún puedas asignar estos en la pila si estás dispuesto a pasar por algunos aros para ser intencionalmente malvado ... pero en mi humilde opinión esto protege de la mayoría de los errores inocentes. –

+0

Por lo tanto, inicialmente diseñamos clases de solo montón ... ¿Este enfoque es ampliamente utilizado? – cybevnm

+0

¿Por qué necesita desactivar el operador de asignación? Por lo general, es correcto asignar a/desde objetos almacenados en shared_ptr. Se manejaría de la misma manera que cualquier otra asignación entre dos objetos * existentes *: los recuentos de referencia no se verían afectados. Los dos * diferentes * objetos solo tendrían los mismos contenidos después de la asignación. – nobar

Cuestiones relacionadas