2

假设我们有一个这样的类:

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

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

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

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

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

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

4

2 回答 2

6

简短的回答是Somewhat


长答案是: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从它移出后执行除破坏/分配之外的任何其他操作都是未定义的行为。

于 2013-11-02T14:44:25.703 回答
0

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

另一个技巧是在它的构造函数ProcessBase中定义和调用它。的构造函数在派生构造函数之前调用,因此确保在派生类中进行任何逻辑之前调用它。initProcessBaseinit

编辑:

  • 您可能希望更改逻辑以使这两种方法都私有并调用一个方法process3(),该方法将以正确的顺序调用其他方法。
  • 另一种选择是使用decorator设计模式并将一个方法包装在一个类中,并让您的装饰器按顺序调用它们。
于 2013-11-02T14:23:09.313 回答