我应该声明这些方法是什么?

sta*_*lue 13 c++ const static-code-analysis const-method

我正在研究一些C++代码,其中我有几个私有方法的管理器对象,如

void NotifyFooUpdated();
Run Code Online (Sandbox Code Playgroud)

OnFooUpdated()在该对象的侦听器上调用该方法.

请注意,它们不会修改此对象的状态,因此它们在技术上可以成为const方法,即使它们通常会修改整个系统的状态.特别是,侦听器对象可能会回调此对象并对其进行修改.

就我个人而言,我想留下它们,而不是宣布它们const.

但是,我们的静态代码检查器QAC将此标记为偏差,因此我要么必须声明它们const,要么我必须争论为什么它们应该保持非常量并获得偏差的授权.

没有声明这些方法的论据是什么const
或者我应该关注QAC并宣布它们const
我应该采用仅限于此对象的严格本地观点,还是将系统视为一个整体?

Ben*_*son 3

宽松地说,您有一个容器类:一个充满观察者的管理器。在 C 和 C++ 中,您可以拥有带有非常量值的 const 容器。考虑一下是否去掉了一层包装材料:

list<Observer> someManager;

void NotifyFooUpdated(const list<Observer>& manager) { ... }
Run Code Online (Sandbox Code Playgroud)

您不会发现全局 NotifyFooUpdated 采用 const 列表有什么奇怪的,因为它不会修改列表。该 const 参数实际上使参数解析更加宽松:该函数接受 const 和非常量列表。类方法版本上的所有 const 注释的含义都是const *this

从另一个角度来说:

如果您不能保证调用该函数的对象在函数调用之前和之后保持相同,那么通常应该将其保留为非常量。

仅当调用者拥有对该对象的唯一引用时,这才是合理的。如果对象是全局的(就像在原始问题中一样)或在线程环境中,则任何给定调用的常量性并不能保证对象的状态在整个调用过程中保持不变。没有副作用并且对于相同输入始终返回相同值的函数是pure。NotifyFooUpdate() 显然不是纯粹的。

  • 如果这是在代码审查中出现的,我可能不会反对任何一种方式,除非有其他因素在起作用。如果每个人都在访问全局并且没有传递 const 引用,那真的没关系。我强烈不同意静态分析可以告诉你这个方法是否应该是 const 的前提:静态分析告诉你它*可能*是 const *作为实现的*,但它不知道你是否打算稍后增强该功能(例如统计数据、消息队列、重复删除或者其他什么)。 (2认同)