【问题标题】:How to design a class method can only be invoked once如何设计一个类方法只能调用一次
【发布时间】:2020-05-19 18:56:54
【问题描述】:

我有有状态的类,一旦创建了一个类实例,它的 Bar 函数/方法只能调用一次,否则内部状态会混乱。这种东西怎么设计?

在编译时可以发出警告/错误会更好。

class  Foo {
  bool Bar(string arg...) { do something...}

  // some class member 
  string s;
  int i;
}

【问题讨论】:

  • bool bar_called_ = false; bool Bar () { if (bar_called_) return false; // or throw exception 中的私有变量,后跟bar_called = true;
  • 谢谢戴夫,我刚刚编辑了这个问题:在编译时最好有一些东西。我在代码中看到了几件事: 1. cmets 说它应该使用一次。 2. 调用 Bar() 时重置状态。
  • 我的猜测是编译时的任何事情都可能只是将上述内容隐藏在宏或类或类似物中,或者会使 Bar 成为构造函数的一部分,但也许其他人会提供建议。
  • 我担心您无法在编译时实现该行为,至少如果您希望能够从项目的任意部分调用 Bar 则不会。
  • 这种技术通常称为“类型状态编程”,并且(据我所知)只能在具有线性类型系统的语言中完成(即,您可以从中删除“用完”的变量范围)。这是example in Rustan approximation in C++

标签: c++ class oop design-patterns


【解决方案1】:

您可以在Foo::Bar() 中定义一个静态标志,用于跟踪函数是否已被调用:

bool Foo::Bar() {
   static bool has_been_called; // initialized to false

   if (!has_been_called) {
      has_been_called = true
      // ...
      // do something
      // ...
      return true;
   }

   return false;
}

对于多个线程可能调用成员函数的情况,可以 改用std::call_once();因为上面的标志has_been_called的读取与写入不同步。

bool Bar() {
   static std::once_flag flag;

   bool executed = false; 

   std::call_once(flag, [this, &executed]() {
      // ...
      // do something
      // ...
      executed = true;
   });
   return executed;
}

【讨论】:

    猜你喜欢
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    相关资源
    最近更新 更多