Dada una interfaz abstracta y una implementación derivada de esa interfaz, donde los constructores están protegidos (la creación de estos objetos solo está disponible en una fábrica de clases para implementar un patrón DI), ¿cómo puede Hago uso de make_shared en la función de fábrica?Uso de make_shared con un constructor protegido + interfaz abstracta
Por ejemplo:
class IInterface
{
public:
virtual void Method() = 0;
};
class InterfaceImpl : public IInterface
{
public:
virtual void Method() {}
protected:
InterfaceImpl() {}
};
std::shared_ptr<IInterface> Create()
{
std::shared_ptr<IInterface> object = std:: make_shared<InterfaceImpl>();
return object;
}
make_shared obviamente no puede acceder al constructor protegida en InterfaceImpl, o incluso en IInterface, y me da el siguiente error
error C2248: 'InterfaceImpl::InterfaceImpl' : cannot access protected member declared in class 'InterfaceImpl'
Así leer aquí (pregunta: How to make boost::make_shared a friend of my class), Intenté incluir lo siguiente en la clase de implementación:
friend std::shared_ptr<InterfaceImpl> std::make_shared<InterfaceImpl>();
Aún no compilaría. Así que también puse otro en la clase IInterface. Todavía no hay alegría. ¿Qué he hecho mal aquí?
EDIT: archivo de código fuente completo utilizado para compilar, con "amigo" ...
#include <memory>
class IInterface
{
public:
friend std::shared_ptr<IInterface> Create();
virtual void Method() = 0;
};
class InterfaceImpl : public IInterface
{
public:
virtual void Method() {}
protected:
friend std::shared_ptr<IInterface> Create();
InterfaceImpl() {}
};
std::shared_ptr<IInterface> Create()
{
std::shared_ptr<IInterface> object = std::make_shared<InterfaceImpl>();
return object;
}
void main()
{
std::shared_ptr<IInterface> i = Create();
}
Supongo que es VC10? GCC btw no tiene problemas siempre y cuando se haga amigo de 'make_shared()'. –
Es VS2010, que en realidad da una advertencia (erróneamente, se detalla aquí: http://connect.microsoft.com/VisualStudio/feedback/details/321690/c-vc9-bogus-warning-c4396-for-valid-code). – Robinson