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

时间:2013-11-02 14:14:22

标签: c++ compiler-errors

假设我们有这样一个类:

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

当函数Process1()尚未被调用时,函数Process2()只能被称为

有没有办法检查Process类在编译时是否正确使用? I.e。如果在Process2()之前为某些OProcess对象实例调用Process1(),则编译器必须给出错误。

P.S。我知道可以有这样的代码:

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

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

2 个答案:

答案 0 :(得分:6)

简短的回答是有点


答案很长:C ++没有实现Linear Typing,因此无法在编译时(完全)完成唯一性检查。尽管如此,阅读这个描述给了我们一个技巧:在编译器中实现它,语言设计者禁止别名并强制执行消费

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

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的代理,提供受限制的界面,仅公开OProcess之后Process1允许的操作

检查的运行时部分是:

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

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

答案 1 :(得分:0)

正确的方法是将init设为私有并降低你提到的风险, 或使用依赖注入,作为'init'方法,或构造函数内部的任何逻辑,在清洁代码方面都是不好的做法

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

编辑:

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