ОК, я думаю, что понимаю более или менее. Если библиотека уже скомпилирована, вы не можете изменить реализацию этого статического метода фабрики. Если вы предоставляете свою собственную реализацию и пытаетесь связать ее с существующей библиотекой, у вас будет несколько определений (не разрешено). Что вы можете сделать, это добавить один слой к вашему приложению, который будет отвечать за создание Base
объектов:
// existing implementation
class Base {
public:
virtual ~Base();
static std::shared_ptr<Base> createInstance() {
return std::shared_ptr<Base>(new Base());
}
private:
Base() {};
};
// new layer, part of your production code
class IYourFactory {
public:
virtual ~IYourFactory() = default;
virtual std::shared_ptr<Base> createInstance() = 0;
};
// new layer, part of your production code
class ProductionFactory: public IYourFactory {
public:
~ProductionFactory() override = default;
std::shared_ptr<Base> createInstance() override {
return Base::createInstance();
}
};
// testing code, you can use GMock to create this class
class MockBase: public Base {
public:
// it's a hack for Base private default constructor
MockBase(): Base(*Base::createInstance()) {}
~MockBase() override = default;
};
// testing code, you can use GMock to create this class
class MockFactory: public IYourFactory {
~MockFactory() override = default;
std::shared_ptr<Base> createInstance() override {
return std::make_shared<MockBase>();
}
};
class YourSystem {
public:
YourSystem(std::shared_ptr<IYourFactory> factory): factory_(factory) {}
bool doSomeThings() {
auto basePtr = factory_->createInstance();
return true;
}
private:
std::shared_ptr<IYourFactory> factory_;
};
Конечно, он будет работать только в том случае, если в классе Base
есть некоторые виртуальные функции, которые вы можете override
в своем MockBase
. Если нет, то это не тот путь (вам нужно создать собственный интерфейс для методов, предлагаемых Base
).
Точное решение зависит от того, как вы используете его в своей системе и каков интерфейс к Base
.