#include <memory>
#include <iostream>
struct ABC {
virtual ~ABC(){}
virtual int getValue() const { return 42; }
};
struct DerivedABC : ABC {
int getValue() const override { return -1; }
};
class XYZFactory {
public:
virtual ~XYZFactory(){}
virtual std::unique_ptr<ABC> createABC() const = 0;
};
class XYZFactoryImpl : public XYZFactory {
public:
std::unique_ptr<ABC> createABC() const override {
return std::make_unique<ABC>();
}
};
class ExtendedXYZFactoryImpl : public XYZFactory {
public:
std::unique_ptr<ABC> createABC() const override {
return std::make_unique<DerivedABC>();
}
};
namespace details { // Or hide this in an anonymous namespace in a .cpp file.
std::unique_ptr<XYZFactory>& getXYZFactoryInstanceMutable() {
static std::unique_ptr<XYZFactory> singleton = std::make_unique<XYZFactoryImpl>();
return singleton;
}
}
const XYZFactory& getXYZFactoryInstance() {
auto& singleton = details::getXYZFactoryInstanceMutable();
if (!singleton)
throw std::runtime_error("No XYZFactory registered");
return *singleton;
}
void setXYZFactoryInstance(std::unique_ptr<XYZFactory> new_factory) {
details::getXYZFactoryInstanceMutable() = std::move(new_factory);
}
int main() {
auto abc = getXYZFactoryInstance().createABC();
std::cout << abc->getValue() << "\n";
setXYZFactoryInstance(std::make_unique<ExtendedXYZFactoryImpl>());
auto extended_abc = getXYZFactoryInstance().createABC();
std::cout << extended_abc->getValue() << "\n";
}