Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;静态成员变量的核心指南_C++_Static Members_Clang Tidy_Cpp Core Guidelines - Fatal编程技术网

C++ C++;静态成员变量的核心指南

C++ C++;静态成员变量的核心指南,c++,static-members,clang-tidy,cpp-core-guidelines,C++,Static Members,Clang Tidy,Cpp Core Guidelines,我的类中有一个私有的静态向量,它保持一个指向从它创建的所有对象的指针。这是必要的,因为每个对象都需要访问所有其他对象的信息以执行某些计算: //头文件: 课例{ 公众: 示例(); 私人: 静态std::向量示例; }; //Cpp文件: std::vector Example::examples_={}; 示例::示例(){ //初始化 示例:安置回(本); } void示例::DoCalc(){ 例如(自动示例:示例){ //做事 } } CLAN-TIDY 指出我违反C++核心准则,

我的类中有一个私有的静态向量,它保持一个指向从它创建的所有对象的指针。这是必要的,因为每个对象都需要访问所有其他对象的信息以执行某些计算:

//头文件:
课例{
公众:
示例();
私人:
静态std::向量示例;
};
//Cpp文件:
std::vector Example::examples_={};
示例::示例(){
//初始化
示例:安置回(本);
}
void示例::DoCalc(){
例如(自动示例:示例){
//做事
}
}

<代码> CLAN-TIDY 指出我违反C++核心准则,即:“变量”示例“是非const的,全局可访问的,考虑使它成为const()”。 就我个人而言,我看不出我的代码和核心指南中的示例代码之间有什么相似之处,特别是因为变量位于类内部且是私有的。实现此功能的“正确”方式是什么?如果可以避免的话,我不想禁用这个检查

就我个人而言,我看不出我的代码与核心指南中的示例代码有什么相似之处

您有一个可供每个线程访问的变量,对
Example
的用户隐藏。与普通全局变量的唯一区别在于它是
私有的
,即不能在
示例
之外使用名称
示例::示例
来引用它

注意

规则是“避免”,而不是“不要使用”

实现此功能的“正确”方法可能是如何实现它,但我强烈建议您修改“每个对象都需要访问所有其他对象的信息才能执行某些计算”,以便将
std::vector
传递到所需的位置,同时跟踪所有相关的(尤其是活动的)
示例
s使用它们的位置

备选方案:[…]另一种解决方案是将数据定义为某个对象的状态,将操作定义为成员函数

警告:当心数据竞争:如果一个线程可以访问非本地数据(或通过引用传递的数据),而另一个线程执行被调用方,则可能会发生数据竞争。每个指向可变数据的指针或引用都是潜在的数据竞争


你做的很好。这就是class-
static
的真正目的。有些人会出于不相关的原因推荐替代方案,这可能值得考虑……但这并不是因为
clangtidy
在这里告诉你的任何事情

你遇到了麻烦。您可以看到这一点,因为它的消息传递是错误的:向量不是“全局可访问的”,至少不是在访问规则的意义上,因为它被标记为
private
(尽管它在翻译单元中全局存在,这很好)


您的代码与引用的核心指南不相关。

一个可能的解决方案是强制访问
Example::examples\uuu
的每个客户端执行一个函数。然后将
示例
作为静态变量放入该函数中。这样,对象将在第一次调用函数时创建-与任何全局对象构造顺序无关

// Header file:
class Example {
public:
    Example();
private:
    std::vector<const Example*>& examples();
};
// Cpp file:
std::vector<Example *>& Example::examples()
{
    static std::vector<Example *> examples_;
    return examples_;
};
Example::Example() {
    // intialization
    examples().emplace_back(this);
}
void Example::DoCalc() {
    for (auto example : examples()) {
        // do stuff
    }
}
//头文件:
课例{
公众:
示例();
私人:
std::vector&examples();
};
//Cpp文件:
std::vector和Example::examples()
{
静态std::向量示例;
返回示例;
};
示例::示例(){
//初始化
示例().向后放置(此);
}
void示例::DoCalc(){
例如(自动示例:examples()){
//做事
}
}
当然,如果您确定全局对象没有问题,并且在构建过程中没有其他全局对象正在访问
Examples::Examples\uu
,则可以忽略该警告。这只是一个指南,你不需要严格遵守

如有翅膀的小行星所述,指南I.2不适用于您的代码。但请注意,CoreGuidelines也打算禁止静态成员,请参见:

避免静态类成员变量(竞争条件,几乎全局变量)


也许这和SOIF有关。如果你有C++ 17,就定义内联静态成员,看看警告是否消失。我已经做C++工作了很长时间。我从来没有想到可变静态类成员有什么根本性的问题。文档提到的唯一潜在问题是静态初始化订单失败。这是真的,但不是否认所有静态类成员的理由,然后删除
std::vector Example::examples_={}来自cpp文件。你还收到警告吗?@SamVarshavchik和数据竞赛,以及你正在用gcc隐藏dependancies的事实,这不会编译,因为你在这里省略了
const
std::vector Example::examples.={}。但我想这只是一个输入错误,而不是你真正的问题。“与普通全局变量的唯一区别在于它是私有的。”但这是一个基本区别,直接关系到引用指南的核心。尽管如此,仍然存在数据争用和远距离行动问题。他们被局限于
示例
,但仍然没有先例,clang tidy正在使用不适用的规则进行投诉,这就是这个问题的内容。这实际上是在LLVM问题跟踪器上提出的,它与作用域无约束全局变量的竞争相同。竞争不会改变,只是有多少代码可能导致竞争。你当然是正确的,CLANTY非常概括C++核心准则规则,但它仍然是一个有效的警告。@ CalthEt,我们可以选择其他方法来实现这样一个线程介绍的类中断,因为它没有相互E。