Здравствуйте!
Подскажите пожалуйста, плохо ли использовать (и почему плохо) std::unique_ptr , std::call_once и std::once_flag в следующем контексте:
template<typename T>
class ResourceCreator {
private:
std::unique_ptr<T> _resource;
std::once_flag _initFlag;
public:
void Init() {
std::call_once(_initFlag, [&]() { _resource.reset(new T()); });
}
std::unique_ptr<T> &getResource() {
return _resource;
}
~ResourceCreator() {
_resource.release();
}
};
template<typename T>
class ResourceCreatorArgs {
private:
std::unique_ptr<T> _resource;
std::once_flag _initFlag;
public:
template<typename... Args>
void Init(Args... constructorArgs) {
std::call_once(_initFlag, [&]() { _resource.reset(new T(std::forward<Args>(constructorArgs)...)); });
}
std::unique_ptr<T> &getResource() {
return _resource;
}
~ResourceCreatorArgs() {
_resource.release();
}
};
template<typename T>
class ResourceCreatorAndOnceRun {
private:
ResourceCreator<T> _creator;
std::once_flag _onceRun;
public:
void Init(std::function<void()> func) {
_creator.Init();
std::call_once(_onceRun, func);
}
std::unique_ptr<T> &getResource() {
return _creator.getResource();
}
};
template<typename T>
class ResourceCreatorArgsAndOnceRun {
private:
ResourceCreatorArgs<T> _creator;
std::once_flag _onceRun;
public:
void Init(std::function<void()> func, Args... constructorArgs) {
_creator.Init(constructorArgs...);
std::call_once(_onceRun, func);
}
std::unique_ptr<T> &getResource() {
return _creator.getResource();
}
};
Сценарий использования этих велосипедов:
namespace {
ResourceCreatorArgsAndOnceRun<Loger> _loger;
}
inline void initLogging() {
std::string fileName = getLogFileName(); // имя файла содержит время старта программы
_loger.InitAndRun([&]() { createLogFile(fileName); }, fileName);
}
#define TO_LOG(text) \
_loger.getResource().get()->save(LogEntry(__FILE__, __PRETTY_FUNCTION__, __LINE__, (text)));
P.S. Если код не очень, скажите пожалуйста, где косяки =)
Заранее спасибо!