对于类的私有类成员M的延迟初始化是否有最佳实践C?例如:
class C {
public:
C();
// This works properly without m, and maybe called at any time,
// even before startWork was called.
someSimpleStuff();
// Called single time, once param is known and work can be started.
startWork(int param);
// Uses m. Called multiple times.
// Guaranteed to only be called after startWork was called
doProcessing();
private:
M m;
};
class M {
M(int param);
};
Run Code Online (Sandbox Code Playgroud)
C无法构造类的对象,因为M没有默认初始值设定项.
如果你可以修改M的实现,可以添加一个init方法M,并使其构造函数不接受任何参数,这将允许构造类的对象C.
如果没有,你可以包装C的成员m中std::unique_ptr,构建它时,它成为可能.
但是,这两种解决方案都容易出现错误,这些错误会在运行时捕获.有一些做法,以确保在编译时即m只对其进行了初始化后使用?
限制:C类的对象被传递给使用其公共接口的外部代码,因此C的公共方法不能分成多个类.
最佳做法是从不使用延迟初始化.
在您的情况下,抛弃默认构造函数C并替换它C(int param) : m(param){}.也就是说,类成员使用基本成员初始化在构造点初始化.
使用延迟初始化意味着您的对象可能处于未定义状态,并且实现诸如并发之类的事情更难.
我会选择 unique_ptr ...您在哪里看到问题?使用M时,您可以轻松检查:
if(m)
m->foo();
Run Code Online (Sandbox Code Playgroud)
我知道这不是编译时检查,但据我所知,当前的编译器无法进行检查。代码分析必须非常复杂才能看到这样的东西,因为只要您愿意,您就可以在任何方法中初始化 m,或者 - 如果是公共/受保护的 - 甚至在另一个文件中。编译时检查意味着延迟初始化是在编译时完成的,但延迟初始化的概念是基于运行时的。