c++ - smart - ¿Puede Google simular un método con un tipo de retorno de puntero inteligente?
smart pointer c++ (2)
Tengo una fábrica que devuelve un puntero inteligente. Independientemente del puntero inteligente que utilice, no puedo hacer que Google Mock se burle del método de fábrica.
El objeto simulado es la implementación de una interfaz abstracta pura donde todos los métodos son virtuales. Tengo un prototipo:
MOCK_METHOD0(Create, std::unique_ptr<IMyObjectThing>());
Y entiendo:
"...gmock/gmock-spec-builders.h(1314): error C2248: ''std::unique_ptr<_Ty>::unique_ptr'' : cannot access private member declared in class ''std::unique_ptr<_Ty>''"
El tipo señalado en el puntero inteligente está definido.
Y entiendo que está tratando de acceder a uno de los constructores declarados privados, pero no entiendo por qué. Cuando esto era un std :: auto_ptr, el error decía que no había un constructor de copia, lo cual me confunde.
De todos modos, ¿hay alguna forma de simular un método que devuelve un puntero inteligente? ¿O hay una mejor manera de construir una fábrica? ¿Mi única determinación es devolver un puntero sin formato (blech ...)?
Mi entorno es Visual Studio 2010 Ultimate y Windows 7. No estoy usando CLI.
Google Mock requiere que los parámetros y los valores devueltos de los métodos simulados se puedan copiar, en la mayoría de los casos. Según la documentación de boost, unique_ptr no se puede copiar. Tiene la opción de devolver una de las clases de punteros inteligentes que usan propiedad compartida ( shared_ptr , linked_ptr, etc.) y, por lo tanto, se pueden copiar. O puede usar un puntero sin formato. Como aparentemente el método en cuestión es el método para construir un objeto, no veo ningún problema inherente al devolver un puntero sin formato. Siempre que asigne el resultado a un puntero compartido en cada sitio de llamada, estará bien.
Una solución factible para los problemas del marco de Google Mock con los argumentos de la función no (const) y los valores reenganchados es usar métodos simulados de proxy.
Supongamos que tiene la siguiente definición de interfaz (si es bueno usar std::unique_ptr
de esta manera parece ser más o menos una cuestión filosófica, personalmente me gusta aplicar la transferencia de propiedad):
class IFooInterface {
public:
virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) = 0;
virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() = 0;
virtual ~IFooInterface() {}
};
La clase simulada apropiada podría definirse así:
class FooInterfaceMock
: public IFooInterface {
public:
FooInterfaceMock() {}
virtual ~FooInterfaceMock() {}
virtual void nonCopyableParam(std::unique_ptr<IMyObjectThing> uPtr) {
nonCopyableParamProxy(uPtr.get());
}
virtual std::unique_ptr<IMyObjectThing> nonCopyableReturn() {
return std::unique_ptr<IMyObjectThing>(nonCopyableReturnProxy());
}
MOCK_METHOD1(nonCopyableParamProxy,void (IMyObjectThing*));
MOCK_METHOD0(nonCopyableReturnProxy,IMyObjectThing* ());
};
Solo debe tener cuidado, las configuraciones (Acciones tomadas) para el método nonCopyableReturnProxy()
devuelven NULL
o una instancia asignada dinámicamente en el montón.
Hay un hilo de foro de usuarios de Google Mock que discute este tema en el que uno de los mantenedores afirma que el framework de google-mock no se cambiará para admitir esto en el futuro argumentando que sus políticas desaconsejan fuertemente los parámetros std::auto_ptr
uso. Como se mencionó, este es en mi humilde opinión un punto de vista filosófico, y las capacidades del marco burlón no deben dirigir qué tipo de interfaces quieres diseñar o puedes usar de API de terceros.
Como se dijo, la respuesta describe una solución factible .