连续函数调用的编译时检查

Compile time check for consecutive functions call

本文关键字:检查 编译 函数调用 连续      更新时间:2023-10-16

假设我们有这样的类:

class OProcess {
  ...
  void Process1();
  void Process2(); // call only if Process1 wasn't called
  ...
}

这样函数 Process2() 只有在函数 Process1() 尚未被调用时才可以调用。

有没有办法检查进程类在编译时是否正确使用? 即,如果 Process1() 可以在 Process2() 之前调用 OProcess 对象的某个实例,编译器必须给出一个错误。

附言我知道可以有这样的代码:

 if (variable == 1000)
   Process1();
 Process2();

并且编译器无法确定 Process1() 将在 Process2() 之前调用。但是在这里编译器可以确定 Process1() 可以在 Process2() 之前调用某些变量值。我需要它来犯错误或至少警告。

简短的回答是有点


长答案是:C++没有实现线性类型,因此无法在编译时(完全)进行唯一性检查。尽管如此,阅读此描述给了我们一个技巧:要在编译器中实现这一点,语言设计器禁止混叠并强制使用

因此,如果您同意允许某些运行时检查,则可以通过让进程使用该对象来完成此操作:

class OProcess {
public:
};
std::unique_ptr<OProcessed1> process1(std::unique_ptr<OProcess> op);
std::unique_ptr<OProcess>    process2(std::unique_ptr<OProcess> op);

其中OProcessed1是一个代理,OProcess提供了一个受限制的接口,该接口仅公开在调用Process1OProcess允许的操作。

检查的运行时部分是:

void func(std::unique_ptr<OProcess> op) {
    process1(std::move(op));
    process2(std::move(op));
}

将编译,即使从它移动后执行除销毁/分配给op以外的任何操作都是未定义的行为。

正确的方法是将 init 设为私有并降低您提到的风险,或者使用依赖注入,因为"init"方法或构造函数内的任何逻辑在干净代码方面都是不好的做法

另一个技巧是使用定义init并在其构造函数中调用它的ProcessBaseProcessBase 的构造函数在派生构造函数之前调用,从而确保在派生类中创建任何逻辑之前调用init

编辑:

  • 您可能希望将逻辑更改为两个方法的私有,并具有一个名为 process3() 的方法,该方法将按正确的顺序调用其他方法。
  • 另一种选择是使用 decorator 设计模式并将一个方法包装在一个类中,并让装饰器按顺序调用它们。