我正在尝试在C ++中实现延迟初始化,并且当我调用Initialize()
之类的其他方法时,我正在寻找一种调用object->GetName()
成员函数的好方法。
现在我已按如下方式实施:
class Person
{
protected:
bool initialized = false;
std::string name;
void Initialize()
{
name = "My name!"; // do heavy reading from database
initialized = true;
}
public:
std::string GetName()
{
if (!initialized) {
Initialize();
}
return name;
}
};
这正是我目前所需要的。但是为每个方法设置初始化检查是非常繁琐的,所以我想摆脱它。如果有人在C ++中知道如何改进上面的例子,我想知道!
在使用operators
时,可能会Initialize()
用于实现调用->
吗?
谢谢!
答案 0 :(得分:2)
听起来像模板的工作!创建一个lazily_initialized
包装器,它采用类型T
和功能对象 TInitializer
类型:
template <typename T, typename TInitializer>
class lazily_initialized : TInitializer
{// ^^^^^^^^^^^^^^
// inheritance used for empty-base optimization
private:
T _data;
bool _initialized = false;
public:
lazily_initialized(TInitializer init = {})
: TInitializer(std::move(init))
{
}
T& get()
{
if(!_initialized)
{
static_cast<TInitializer&>(*this)(_data);
_initialized = true;
}
return _data;
}
};
您可以按如下方式使用它:
struct ReadFromDatabase
{
void operator()(std::string& target) const
{
std::cout << "initializing...\n";
target = "hello!";
}
};
struct Foo
{
lazily_initialized<std::string, ReadFromDatabase> _str;
};
示例:
int main()
{
Foo foo;
foo._str.get(); // prints "initializing...", returns "hello!"
foo._str.get(); // returns "hello!"
}
在评论中提及Jarod42时,应使用std::optional<T>
或boost::optional<T>
代替单独的bool
字段,以表示&#34;未初始化状态&# 34 ;.这允许非默认构造类型与lazily_initialized
一起使用,并且还使代码更优雅,更安全。
由于前者需要C ++ 17而后者需要boost
,因此我使用单独的bool
字段使我的答案尽可能简单。真正的实现应考虑使用optional
,在适当的情况下使用noexcept
,并考虑公开const
- 合格的get()
,其返回const T&
。
答案 1 :(得分:-2)
也许在构造函数中调用它?
编辑:呃,我错过了你的问题,抱歉。 懒惰的工厂初始化怎么样? https://en.wikipedia.org/wiki/Lazy_initialization#C.2B.2B