跨类的多个实例调用函数一次

Call function once across multiple instances of a class

本文关键字:一次 函数 调用 实例      更新时间:2023-10-16

我已经环顾四周一段时间了,似乎找不到答案。
那么,如果我有一个类的多个实例,我怎么能从该类的所有实例中只调用一次函数呢?
例如,如果我在一个名为myClass的类中有一个名为myFunc()的函数,并且该类的两个实例名为class1class2,那么
class1.myFunc()应该返回 1,class2.myFunc()
应该返回 0,class1.myFunc()
应该返回 0。

我该怎么做?

class myClass{
public:
myClass(){}
int myFunc(){
if (myFuncHasBeenCalled){
return 0;
}
else{
return 1;
}
}
}
myClass class1;
myClass class2;
class1.myFunc(); //would output 1
class2.myFunc(); //would output 0
class1.myFunc(); //would output 0

你可以通过以下方式实现

  • 引入类变量,在类声明中使用static关键字
  • 在(单独的)代码文件中定义类变量,并具有初始化
  • 在函数内部检查,如果 0 输出 1 否则 0
  • 之后增加(或设置为非零)
  • 小心使用同步机制,以防调用可能来自不同的上下文/线程/任务/进程(无论您的环境中适用什么)

(如果您展示您对静态变量的尝试并解释您遇到的问题,这可能会变得更加详细。

您有几个可用的选项: 这个想法是,您需要具有一些可以独立于类实例访问的值。static是在所有情况下执行此操作的方法(除非不是)。

选项一是最佳选择 -- 成员函数中的静态变量

我推荐的方法是在成员函数中使用静态变量;这样可以避免污染类本身,并使您更容易在更新中保持一致的 ABI 和一致的 API。对代码进行推理非常容易,因为您不允许任何其他内容访问该变量。

例:

struct S {
int F() const {
static int n = 1;
if (n == 1) {
n = 0;
return 1;
}
return n;
}
};

选项二是坏选项 -- 类中的静态变量

另一种似乎很流行的方法是保留静态成员变量。这允许您执行与上一个示例相同的操作,但使在升级期间维护 API 和 ABI 变得更加困难。它还使推理代码变得更加困难,并且更容易引入错误 - 静态成员变量与全局变量没有太大区别。

例:

struct S {
static int n;
int F() const {
if (n == 1) {
n = 0;
return 1;
}
return n;
}
};
int S::n = 1;

选项三是最糟糕的选择——全局变量

最糟糕的替代方法是使用全局变量。我不会给你们举一个例子——不要这样做。如果您仍然必须这样做(您没有),请在.cpp文件的匿名命名空间中声明您的变量。

namespace {
int n = 0
}

选项四 - 好选择

另一种方法是使用静态成员函数。此函数完全独立于类的所有实例。实现中唯一的区别是将static添加到函数声明中 - 否则,可以使用前两个选项。不过,这并非在所有情况下都可行。

注意事项和其他说明

如果需要使用该变量在两个函数之间传递状态,则必须使用全局选项之一,并且不能在成员函数中使用静态变量。

在所有情况下,如果您不修改实例,则应将函数标记为const

你应该真正使用std::atomic变量你应该使用某种机制来保证你的代码是线程安全的。

相关文章: