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(尽管它在翻译单元中全局存在,这很好)。
您的代码与引用的核心指南无关。
一种可能的解决方案是强制每个访问的客户端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:
避免静态类成员变量(竞争条件,几乎全局变量)