ein*_*ica 9 c++ idioms idiomatic
我有以下代码:
MyType x = do_something_dangerous();
// ...
if (some_condition) {
// ...
bar(x);
}
else {
// ...
}
// ...
if (another_condition_which_may_depend_on_previous_if_else} {
// ...
baz(x);
}
Run Code Online (Sandbox Code Playgroud)
这个想法是,在某些情况下,我可能需要使用,这可能是事先确定的难度/不方便x.但是在我不需要使用它的情况下,尝试初始化它可能是不好的(比如说,可能会导致我的进程崩溃).
现在,似乎我需要使用的是一个初始化按需持有者(链接侧重于Java,所以这里是一个草图):某种Wrapper<MyType>或Wrapper<MyType, do_something_dangerous>一种get()方法,这样第一次get()调用do_something_dangerous(),后来get()只是通过第一次通话获得的价值.
笔记:
boost::optional,但这有点麻烦,也扭曲了预期的用途:"建议optional<T>在没有类型的价值,T缺乏的地方,只有一个,清楚(对所有各方)的原因使用价值与任何常规价值一样自然T."恕我直言,你提出的解决方案是完全合适的:
当然,如果你已经在你的应用程序中使用了boost,你可以查看建议的boost :: optional模块,但是我不确定它是否正是你想要的,因为当你需要的东西被推迟时,它更适合于可以为空的对象设计初始化.
我的建议是:坚持专用的包装器实现.
不像其他的答案,我想你应该不使用一个单身,但单纯的喜欢(使用初始化参数实现)的东西:
template<typename T, typename I>
class LazyInit {
T* val;
I init;
public:
LazyInit<T, I>(I init): init(init) {
val = NULL;
}
~LazyInit<T, I>() {
delete val;
val = NULL; // normally useless here
}
T& get() {
if (val == NULL) {
val = new T(init);
}
return *val;
}
};
Run Code Online (Sandbox Code Playgroud)
这是一个使用初始化函数的实现:
template<typename T>
class LazyInit {
T* val;
T (*init)();
public:
LazyInit<T>(T (*init)()): init(init) {
val = NULL;
}
~LazyInit<T>() {
delete val;
val = NULL; // normally useless here
}
T& get() {
if (val == NULL) {
val = new T(init());
}
return *val;
}
};
...
LazyInit<MyType> x(do_something);
...
bar(x.get()); // initialization done only here
Run Code Online (Sandbox Code Playgroud)
您可以轻松地将两者结合起来,使用带参数的函数构建实现.