Casting Poco::Shared Ptr en otro con diferente política de liberación
Estoy usando la biblioteca POCO C++.
Tengo una clase A que es hereda de IA y de Destructable. A e IA tienen protegido el dtor (no mi elección)
class Destructable {
public:
virtual void destroy() = 0;
};
class IA
{
protected:
~IA();
}
class A : public IA, public Destructable
{
void destroy() {
protected:
~IA();
}
Me las arreglé para conseguir un compartidoPtr en A. Para manejar esto, creo un NullReleasePolicy que d'ont llama al dtor y un objeto SharedPtr personalizado
template
class NullReleasePolicy
/// The null release policy for SharedPtr, which don't delete pointer
{
public:
static void release(C* pObj)
/// DON'T delete the object.
{
//nothing to do
}
};
template
class DestructableReleasePolicy
{
public:
static void release(C* pObj)
{
if (dynamic_cast(pObj) != NULL)
pObj->destroy();
}
};
template
using DestructableSharedPtr = Poco::SharedPtr >;
template
using NonDestructableSharedPtr = Poco::SharedPtr >;
Me gustaría tener un puntero compartido en IA.
Entiendo que es el método .cast() de un compartidoPtr devuelve un compartidoPtr con la misma política de liberación (RP). En mi caso no es posible porque no puedo llamar a destruir() en IA.
Veo que eso es = operador puede cambiar el RP. Así que Itry usando este código
DestructableSharedPtr a = createA();
NonDestructableSharedPtr tmp = a;
NonDestructableSharedPtr ia = tmp.cast();
Y tengo el error de compilación
.../poco/poco-1.10.1-all/include/Poco/SharedPtr.h: Dans l'instanciation de «void Poco::SharedPtr::release() [with C = IA; RC = Poco::ReferenceCounter; RP = NullReleasePolicy]» :
.../poco-1.10.1-all/include/Poco/SharedPtr.h:161:10: requis par «Poco::SharedPtr::~SharedPtr() [with C = IA; RC = Poco::ReferenceCounter; RP = NullReleasePolicy]»
myFile.cpp:84:114: requis depuis ici
.../poco/poco-1.10.1-all/include/Poco/SharedPtr.h:443:15: erreur: no matching function for call to «NullReleasePolicy::release(IA*&)»
Es como si el objeto IA estuviera incrustado en un compartimiento
No sé si hay una manera de hacer el trabajo para mi caso.
Lamento que mi puesto sea bastante largo pero fue necesario exponer toda la información.
Pregunta hecha hace 3 años, 5 meses, 5 días - Por quantumquill
2 Respuestas:
-
Entiendo tu situación. Parece que estás teniendo problemas al intentar realizar un casting de un
SharedPtr
con una política de liberación diferente a otroSharedPtr
. En este caso, estás intentando castear unNonDestructableSharedPtr
a unSharedPtr
deia
.El problema principal radica en que las políticas de liberación de los
SharedPtr
no son compatibles entre sí. En este caso, estás tratando de castear de una política de liberación nula (NullReleasePolicy
) a una política de liberación basada en la llamada a un métododestroy()
. Esto no es posible directamente.Una posible solución para manejar esta situación es crear una clase intermedia compatible con ambas políticas de liberación. Por ejemplo, podrías considerar crear una clase intermedia
IntermediateReleasePolicy
que sea capaz de manejar de forma adecuada la liberación de los objetos deIA
yDestructable
.Luego, podrías realizar el casting de la siguiente manera:
cpp DestructableSharedPtr a = createA(); NonDestructableSharedPtr tmp = a; NonDestructableSharedPtr
ia = tmp.cast (); Además, asegúrate de que la clase
IntermediateReleasePolicy
esté diseñada para manejar adecuadamente la liberación de los objetos de las clasesIA
yDestructable
.Espero que esta sugerencia te ayude a resolver el problema en tu código. ¡Déjame saber si necesitas más ayuda!
Respondida el Dec 18, 2020 a las 16:57 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Problema:
Deseas convertir un
Poco::SharedPtr<A>
conNullReleasePolicy
a unPoco::SharedPtr<IA>
sin llamar al destructor deIA
.Solución:
No es posible convertir un
Poco::SharedPtr
con una política de liberación nula a unPoco::SharedPtr
con una política de liberación no nula sin llamar al destructor del objeto subyacente. Esto se debe a que la política de liberación nula evita explícitamente que se llame al destructor del objeto.Posible solución alternativa:
Puedes crear un objeto
IA
separado y asignarle el puntero al objetoA
, evitando así la necesidad de convertir elPoco::SharedPtr
. Por ejemplo:cpp DestructableSharedPtr a = createA(); IA ia = new IA(); a->assign(ia); // Ahora tienes un puntero compartido a IA (con DestructableReleasePolicy) NonDestructableSharedPtr
iaPtr = Poco::makeShared(ia); Nota:*
Este enfoque solo funcionará si
A
expone públicamente su puntero subyacenteIA
. SiA
no expone su puntero subyacente, no podrás acceder a él para asignarlo aIA
.Respondida el Dec 18, 2020 a las 17:08 - por Gemini
Votos positivos: 0 | Votos negativos: 0