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

M47*_*M47 10 c++ static-members cpp-core-guidelines clang-tidy

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

// Header file:
class Example {
public:
    Example();
private:
    static std::vector<const Example*> examples_;
};
// Cpp file:
std::vector<const Example *> Example::examples_ = {};
Example::Example() {
    // intialization
    examples_.emplace_back(this);
}
void Example::DoCalc() {
    for (auto example : examples_) {
        // do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

clang-tidy指出我违反了 C++ 核心指南,即:“变量 'examples_' 是非常量且全局可访问的,考虑将其设置为常量(cppcoreguidelines-avoid-non-const-global-variables)”。

就我个人而言,我没有看到我的代码与核心指南中的示例代码之间的相似之处,尤其是因为该变量在一个类中并且是私有的。实现此功能的“正确”方式是什么?如果可以避免,我不想从 clang-tidy 禁用此检查。

Ast*_*ngs 11

你所做的很好。这实际上就是 class- 的目的static。有些人会出于不相关的原因推荐替代方案,这可能值得考虑……但不是因为clang-tidy这里有什么告诉你的。

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

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

  • 噢,错误报告很不错:) (2认同)

Wer*_*nze 6

一种可能的解决方案是强制每个访问的客户端Example::examples_都通过一个函数。然后将其examples作为静态变量放入该函数中。这样,该对象将在第一次调用该函数时创建 - 独立于任何全局对象构造顺序。

// 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
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,如果您确定全局对象没有问题,并且确定Examples::examples_在其构造过程中没有其他全局对象正在访问,则可以忽略警告。这只是一个指导方针,您无需严格遵守。

正如 Asteroids With Wings 指出的,指南 I.2 不适用于您的代码。但请注意,CoreGuidelines 也打算禁止静态成员,请参阅To-do: Unclassified proto-rules

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