调用对象中的"initialize"函数时调用其成员函数之一
Call an "initialize" function in an object when one of its member functions are called
我正在尝试在C++中实现延迟初始化,并且我正在寻找一种在调用其他方法(如object->GetName()
)时调用Initialize()
成员函数的好方法。
现在我已经实现了如下:
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()
?
谢谢!
听起来像是模板的工作!创建一个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
字段来表示"未初始化的状态"。这允许非默认可构造类型与lazily_initialized
一起使用,并且还使代码更加优雅和安全。
由于前者需要C++17,后者需要boost
,我使用了一个单独的bool
字段来使我的答案尽可能简单。真正的实现应该考虑使用optional
,在适当的情况下使用noexcept
,并考虑公开返回const T&
的const
限定get()
。
也许在构造函数中调用它?
编辑:呃,对不起,我错过了你问题的重点。 惰性工厂初始化呢? https://en.wikipedia.org/wiki/Lazy_initialization#C.2B.2B
相关文章:
- 如何用参数值调用函数(仅在运行时已知)
- 从python中调用C++函数并获取返回值
- 当使用通配符和null指针调用函数时,对输出的说明
- 从R调用C++函数并对其进行集成时出错
- 使用QTreeView,如何通过调用函数只突出显示特定的行/列
- 如何在qt中从另一个类调用函数
- 在 COUT 语句中使用 COUT 调用函数
- 如何从线程中的不同模块调用函数?
- C++从函数指针数组调用函数
- 当 A 在 for 循环中调用函数 B 时,如何计算函数 A 的空间复杂度?
- 如何在 C/C++ 中从外部库调用函数
- 如何使用运算符在同一行中多次调用函数
- 是否可以创建一个从不同类调用函数的线程?
- 无法为类成员调用函数
- 如何从另一个标头 c++ 调用函数
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- 如何只允许在调用函数 B 后调用函数 A?
- 我可以这样调用函数吗?
- 如何在 c++ 的类中递归调用函数方法?
- 为什么在指向对象的迭代器上调用函数不允许我更改对象本身?