为什么谷歌会以成员变量命名访问器和变异器

Why does Google name accessors and mutators after member variables?

本文关键字:访问 变异 变量 谷歌 成员 为什么      更新时间:2023-10-16

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml?showone=Function_Names#Function_Names

正则函数具有混合大小写;accessor和mutator与变量名称:MyExcitingFunction()、MyExcitiingMethod()、,my_exciting_member_variable()、set_my_exciting_mmember_variable()。

封装的全部目的不是向用户隐藏实现细节,这样他/她就不知道访问器/赋值器方法是否返回/修改成员变量吗?如果我更改变量名或更改它在对象中的存储方式,该怎么办?

编辑:

如果我有一个实例变量int foo_,它看起来很简单

int foo() const { return foo_; }

但是如果我添加另一个返回foo_ + 2的方法,我应该命名为bar还是GetBar

int bar() const { return foo_ + 2; }
int GetBar() const { return foo_ + 2; }

如果我选择GetBar,然后决定将返回的值缓存在另一个成员变量bar_中,我是否必须将该方法重命名为bar

实际上,封装的目的是隐藏类的内部工作,而不一定是隐藏事物的名称。成员变量的名称无关紧要;它是访问器或赋值器提供的间接性级别。

使用访问器可以更改类的内部工作方式(包括成员变量的名称),而不会破坏类与外部世界的接口。类的用户不必关心实现细节,包括类内部的名称,而只关心类的行为,从外部来看。

换句话说,类的用户不应该依赖谷歌的风格指南来确定他们是否在修改成员变量

因为谷歌风格的指南只适用于谷歌员工。相反,这不是一个好的风格指南。

举个恰当的例子——他们明确禁止通过非常量引用,因为这可能会"令人困惑"。

所以你是对的,它违背了封装的目的。不要以偏概全。

当考虑一个类时,它在概念上可能是可见的状态,客户端可以访问该状态。这种状态如何在类内表示是另一回事,这就是访问者(getter和setter)隐藏起来。我自己的命名约定也做出了这种区分:如果函数在概念上getter或setter,它具有属性的名称通常是名词;否则,它就是一个动词。和我区分函数正在获取或设置概念上不属于类的内容(例如,部分取决于自变量),具有动词getset,以及函数实际上是在修改概念上的属性,在这种情况下它们不会。

对于其他人,就像大多数风格指南一样,并不是每个人都是同意这一点。我不确定我喜欢他们的名字例如,公约。它们被称为命名约定因为它们只是:任意的约定。唯一真正的硬规则是,类型、宏和其他东西必须可分辨的,并且名称不应以强调(还有一些更温和的规则:我会非常对一个最终命名为局部变量比全局变量长。)

我可能对常识的假设太过分了,但我确信保留已发布的接口比遵循命名指南更重要。

由于您最初的bar/GetBar函数是而不是访问器,因此我认为它应该遵循常规名称指南并称为GetBar

如果稍后引入bar_,使函数在某种意义上成为一个访问器,我确信您不应该删除GetBar。我想你也可以添加一个函数bar(),它被定义为做同样的事情,但我不认为我会把风格指南解释为需要这样做。

我也非常确信,一旦您发布的接口包含您(和调用方)认为是"访问器"的函数,封装在某种程度上就不可能了,因为您谈论的是对象的状态,而不是它的行为。函数返回当前实现中成员变量的值并不意味着必须将其记录为访问器。但是,如果你坚持编写被公众认可为访问器的函数,谷歌告诉你如何命名它们。经典的例子是,一个足够愚蠢的数据记录对象可能有合理的访问器,因为整个类被公开定义为一束可能有一点行为的字段。

我以前读过几次该风格指南,但我从未为谷歌工作过,所以我不知道他们的代码审查如何在实践中应用它。我认为这样规模的组织不可能在每个细节上都完全一致。所以你的猜测可能和我的一样好。