我在我的类中有一个私有的静态向量,它保存了一个指向所有从它创建的对象的指针。这是必要的,因为每个对象都需要访问所有其他对象的信息来执行一些计算:
// 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
}
}
字符串clang-tidy
指出我违反了C++核心准则,即:“变量'examples_'是非常量且全局可访问的,请考虑将其设为常量(cppcoreguidelines-avoid-non-const-global-variables)”。
就我个人而言,我没有看到我的代码和核心准则中的示例代码之间的相似之处,特别是因为变量是在一个类中并且是私有的。实现这个功能的“正确”方法是什么?如果可以避免的话,我不想禁用clang-tidy的这种检查。
3条答案
按热度按时间ux6nzvsh1#
你所做的一切都很好。这就是class-
static
的真正目的。有些人会推荐替代方案,出于不相关的原因,这可能值得考虑.但不是因为clang-tidy
在这里告诉你的任何事情。你已经遇到了
clang-tidy
bug #48040。你可以看到这一点,因为它的消息传递是错误的:向量不是“全局可访问的”,至少在访问规则的意义上不是,因为它被标记为private
(尽管它在翻译单元中全局存在,这很好)。你的代码与引用的核心准则无关。
ohfgkhjo2#
一个可能的解决方案是强制每个访问
Example::examples_
的客户端都要经过一个函数。然后将examples
作为一个静态变量放入该函数中。这样,该对象将在第一次调用该函数时创建-与任何全局对象构造顺序无关。字符串
当然,如果你确定你对全局对象没有问题,并且确定在
Examples::examples_
的构造过程中没有其他全局对象访问它,你可以忽略这个警告。这只是一个指导,你不需要严格遵守它。正如Asteroids With Wings所指出的,准则I.2不适用于您的代码。但请注意,核心准则也打算禁止静态成员,请参阅To-do:Unclassified proto-rules:
避免静态类成员变量(竞争条件,几乎全局变量)
k4aesqcs3#
就我个人而言,我的代码与核心指导原则中的示例代码之间没有相似之处
你有一个变量,每个线程都可以访问,对
Example
的用户隐藏。与普通全局变量的唯一区别是它是private
,也就是说,你不能在Example
之外使用 nameExample::examples_
引用它。备注
规则是“避免”,而不是“不使用”。
实现此功能的“正确”方法可能是您如何拥有它,但我强烈建议您修改“每个对象需要访问所有其他对象的信息以执行某些计算”,以便将
std::vector<const Example*>
传递到需要它的地方,并跟踪所有相关的(特别是活动的)Example
。替代:[...]另一种解决方案是将数据定义为某个对象的状态,将操作定义为成员函数。
**警告:**小心数据竞争:如果一个线程可以访问非本地数据(或通过引用传递的数据),而另一个线程执行被调用者,我们可以有一个数据竞争。每个指向可变数据的指针或引用都是一个潜在的数据竞争。