直接访问成员或始终使用getter

Mr.*_*Boy 18 c++ coding-style

注意:C++特定问题

当一个类使用getter访问自己的成员数据时,我个人觉得它很奇怪/丑陋.我知道性能影响是没有但我只是不喜欢看到所有这些方法调用.是否有任何强有力的论据,或者它只是个人喜好的东西之一,应留给每个编码人员,还是在编码标准中任意控制?

更新:我的意思是简单的吸气剂,特别是对于一个班级的非公共成员.

Sin*_*ion 12

您可能想要使用getter/setter的原因是因为它隐藏了实现.如果您正在使用getter/setter以防实现确实发生更改,则不必重写所有代码,因为这些成员可以继续工作.

编辑基于许多聪明的评论:

至于自己使用setter和getter的类,这可能取决于细节.毕竟,类本身可以使用特定类的实现.在通常实例化类的情况下,类应该直接将成员值用于其自己的成员(私有或其他)及其父类(如果它们受到保护),并且仅在这些成员使用时使用getter/setter.私有父类.

在抽象类型的情况下,它通常根本不包含任何实现,它应该提供纯虚拟的getter和setter,并且只使用它实现的方法中的那些.

  • ...答案也适用于使用它自己的getter/setter的类 (4认同)

Did*_*set 12

在集体成员实施中愿意使用getter/setter是矿井中的金丝雀,告诉你的班级正在不合理地增长.它告诉你的班级正在尝试做太多不同的事情,它有几个目的,它应该服务于一个.

实际上,当您使用类的一部分来存储或访问数据时,通常会遇到这种情况,而另一部分则是对其进行操作.也许你应该考虑使用一个独立的类来存储和访问你的数据,另一个用来提供更高的视图,以及更复杂的数据操作.

  • 它*是一个标志.如果你真的考虑使用`getName()`而不是`name`来实现类实现,那么这意味着你认为你可以从其他地方获得名称.获取名称*是*另一个功能,而不是实际的类功能. (3认同)
  • 调用`getName()`并不意味着我可能会期望这个名字来自其他地方.你将你的思维过程视为全球规则. (2认同)

Ton*_*roy 8

显而易见

受保护成员的getter和setter与public一样有意义......派生类只是客户端代码的另一种形式,从它们封装实现细节仍然很有用.我并不是说总是这样做,只是为了减轻正常线条的利弊.

私人成员的吸气剂和制定者很少是净收益,但是:

  • 它确实提供了相同类型的封装优势

    • 在开发期间断点/记录get/set +不变检查的单个位置(如果一致地使用)
    • 虚拟潜力
    • 等等...

    但仅限于可能相对较小的相同结构/类的实现.在企业环境中,对于公共/受保护的成员数据,这些好处可以足以证明获取/设置方法的合理性:日志记录功能最终可能依赖于数百万行代码,以及数百或数千个库和应用程序对标头的更改可能会触发重新编译.一般来说,单个类的实现不应该超过几百(或最差千)行 - 不足以证明封装内部私有数据的大小或复杂性......可以说它构成了"代码味道".

不那么显眼

  • get/set方法偶尔比直接变量访问更具可读性(尽管通常更不易读)
  • get/set方法可能能够为代码生成的成员或朋友方法(无论是来自宏还是外部工具/脚本)提供更加统一和方便的界面
  • 如果可能的话,在成为成员或朋友之间转换为独立的帮助函数所需的工作量减少
  • 对于通常只是该类用户的人(因为更多操作通过公共接口或以公共接口的方式表达),可以使实现更容易理解(并因此可维护)

这个问题有点超出范围,但值得注意的是,类通常应提供面向操作的命令,事件触发的回调等,而不是鼓励获取/设置使用模式.


Lie*_*yan 5

似乎大多数人没有正确阅读您的问题,该问题是关于访问其自身类成员的类方法是否应使用getter和setter的。与外部实体访问该类的成员无关。

我不会费心使用getter和setter来访问类的成员。

但是,我也将班级缩小(通常约200至500行),这样,如果我确实需要更改字段或更改其实现或它们的计算方式,那么搜索和替换就不会太费力(实际上,在开发的早期阶段,我经常更改变量/类/函数的名称(我是挑剔的名称选择器)。

当我期望在不久的将来更改实现时(例如,如果我正在编写可以快速编写的次优代码,但计划在将来对其进行优化),则仅使用getter和setter访问我自己的类成员可能涉及从根本上更改所使用的数据结构。相反,在我已经有了计划之前,我不使用getter和setter。特别是,我不希望使用getter和setter来更改我很可能永远也不会更改的东西。

但是对于外部接口,我严格遵守公共接口。所有变量都是私有的,friend除运算符重载外,我避免使用;我protected保守地使用成员,他们被认为是公共接口。但是,即使对于公共接口,我通常仍然避免使用直接的getter和setter方法,因为它们通常表示OO设计不良(使用任何语言的每个OO程序员都应阅读:为什么getter和setter方法是Evil)。相反,我有一些方法可以做一些有用的事情,而不仅仅是获取值。例如:

class Rectangle {
    private:
        int x, y, width, height;
    public:
        // avoid getX, setX, getY, setY, getWidth, setWidth, getHeight, setHeight
        void move(int new_x, int new_y);
        void resize(int new_width, int new_height);
        int area();
}
Run Code Online (Sandbox Code Playgroud)