Aarkan
BI estoy usando enable_shared_from_this
en mi código, y no estoy seguro si su uso es correcto. Este es el código:
class A: public std::enable_shared_from_this<A>
{
public:
void foo1()
{
auto ptr = shared_from_this();
}
};
class B:public std::enable_shared_from_this<B>
{
public:
void foo2()
{
auto ptr = shared_from_this();
}
};
class C:public std::enable_shared_from_this<C>
{
public:
void foo3()
{
auto ptr = shared_from_this();
}
};
class D: public A, public B, public C
{
public:
void foo()
{
auto ptr = A::shared_from_this();
}
};
¿Son estos usos de make_shared_from_this()
correcto, asumiendo que siempre están siendo llamados a través shared_ptr
de D?
Ofirmo
Efectivamente lo estás haciendo mal. Si tiene herencia simple, simplemente herede de enable_shared_from this
en la clase base, y la clase derivada lo obtienen gratis. (por supuesto, tendrás que rebajar el resultado)
Si tiene herencia múltiple (como parece), debe usar el truco descrito aquí y también aquí:
/* Trick to allow multiple inheritance of objects
* inheriting shared_from_this.
* cf. https://stackoverflow.com/a/12793989/587407
*/
/* First a common base class
* of course, one should always virtually inherit from it.
*/
class MultipleInheritableEnableSharedFromThis
: public std::enable_shared_from_this<MultipleInheritableEnableSharedFromThis> {
public:
virtual ~MultipleInheritableEnableSharedFromThis()
{}
};
template <class T>
class inheritable_enable_shared_from_this
: virtual public MultipleInheritableEnableSharedFromThis {
public:
std::shared_ptr<T> shared_from_this() {
return std::dynamic_pointer_cast<T>(
MultipleInheritableEnableSharedFromThis::shared_from_this()
);
}
/* Utility method to easily downcast.
* Useful when a child doesn't inherit directly from enable_shared_from_this
* but wants to use the feature.
*/
template <class Down>
std::shared_ptr<Down> downcasted_shared_from_this() {
return std::dynamic_pointer_cast<Down>(
MultipleInheritableEnableSharedFromThis::shared_from_this()
);
}
};
Entonces tu código se convierte en:
class A: public inheritable_enable_shared_from_this<A>
{
public:
void foo1()
{
auto ptr = shared_from_this();
}
};
class B: public inheritable_enable_shared_from_this<B>
{
public:
void foo2()
{
auto ptr = shared_from_this();
}
};
class C: public inheritable_enable_shared_from_this<C>
{
public:
void foo3()
{
auto ptr = shared_from_this();
}
};
class D: public A, public B, public C
{
public:
void foo()
{
auto ptr = A::downcasted_shared_from_this<D>();
}
};
-
Nota: las clases derivadas solo podrán usar el enable_shared_from_this heredado si es público, es decir:
class BaseClass: public enable_shared_from_this<BaseClass>
.– Andrés
30 de mayo de 2017 a las 3:14
-
@Offirmo ¿Hay alguna solución posible en caso de que no pueda modificar (heredar de legacy_enable_shared_from_this) las clases base (A, B, C)?
–Ehtesham Hasan
30 de abril de 2018 a las 4:04
no creo
foo2
ofoo3
compilaria…– Aschepler
18 de abril de 2013 a las 12:23
sí, eso no tiene sentido, solo la clase A hereda enable_shared_from_this
– Stéphane Rolland
18 de abril de 2013 a las 12:40
Creo que deberías echar un vistazo a lo que hace enable_shared_from_this. Ver la respuesta a esta pregunta
– indeterminadamente secuenciado
18 de abril de 2013 a las 12:43
posible duplicado de stackoverflow.com/questions/14939190/…
–Andriy Tylychko
18 de abril de 2013 a las 12:46
si que es mejor 🙂
– Stéphane Rolland
18 de abril de 2013 a las 12:53