如果未调用某些函数,则禁止编译代码
Forbid code to compile if some function is not called
有
没有办法在C++中禁止代码编译,如果未调用特定函数。
想象一下,我有一些课程:
class CExample
{
public:
void Init();
void DoWork();
};
有没有办法禁止调用 DoWork() 如果没有为类对象调用 Init() 函数?
我想禁止编写这样的代码:
CExample e;
e.DoWork();
并允许此版本:
CExample e;
e.Init();
e.DoWork();
我可以通过元编程以某种方式达到这种行为吗?
你可以只使用构造函数而不是Init
.
Bjarne Stroustrup 在标准库中关于异常安全的笔记中,作为第 3 版 The C++ Programming Language 的附录,讨论了使用 init
函数如何与类不变量的概念不一致。这通常是不良做法™,主要是出于这个原因。
一些旧的 GUI 框架(如 Microsoft 的 MFC)使用init
函数来执行派生类特定的初始化。还有其他技术可以做到这一点,包括通过参数将所需的信息传递到构造链上。
不,那将是糟糕的设计。如果必须调用它才能使对象可用,则应在构造函数中调用它。构造对象后,所有公共方法都应该是可调用的 - 对象应该完全构造并可供使用。
在编译时,不知道Init()
是否在DoWork()
之前被调用过。这只能在运行时决定。因此,元编程在这里是没有用的。
您应该将 init 代码放入构造函数中,以强制正确构造该类。但是,如果你真的坚持,并且你的 init 函数真的不是多态的,你可以将 CRTP 与受保护的构造函数一起使用:
template <typename What>
class InitMe : public What
{
public:
InitMe() : What() { this->Init(); }
};
class CExample
{
public:
void Init() {}
void DoWork() {}
protected:
CExample() {}
};
int main()
{
//CExample e; // Error: protected constructor.
InitMe<CExample> e;
e.DoWork();
}
正如 Cheers 和 hth. -Alf 和 Rob K 都提到的那样,你绝对希望在类构造函数中执行你的init
工作。必须调用一个单独的函数来确保你的类正确准备就绪是糟糕的设计。
但是,话虽如此,您可以检测它是否已被调用并采取相应的行动:
void CExample::Init()
{
// things
...
init = true;
}
void CExample::DoWork()
{
if (!init)
{
Init();
}
}