C++中访问器方法(getter和setter)的约定

Noa*_*rth 72 c++ getter setter accessor

关于C++中的访问器方法的几个问题已经被问到,但没有一个能够满足我对这个问题的好奇心.

我试图尽可能避免使用访问器,因为像Stroustrup和其他着名的程序员一样,我认为一个类很多都是OO的标志.在C++中,我可以在大多数情况下为类添加更多的责任或使用friend关键字来避免它们.但在某些情况下,您确实需要访问特定的班级成员.

有几种可能性:

1.根本不要使用存取器

我们可以公开相应的成员变量.这在Java中是不行的,但对于C++社区似乎没问题.但是,我有点担心的情况是一个显式副本或一个对象的只读(const)引用应该返回,是夸大了吗?

2.使用Java样式的get/set方法

我不确定它是否来自Java,但我的意思是:

int getAmount(); // Returns the amount
void setAmount(int amount); // Sets the amount
Run Code Online (Sandbox Code Playgroud)

3.使用客观的C风格的get/set方法

这有点奇怪,但显然越来越普遍:

int amount(); // Returns the amount
void amount(int amount); // Sets the amount
Run Code Online (Sandbox Code Playgroud)

为了使其工作,您必须为您的成员变量找到不同的名称.有些人附加下划线,其他人加上"m_".我也不喜欢.

你使用哪种风格?为什么?

Jus*_*mer 40

从我的角度来看,从维护的角度来看,有400万行C++代码(这只是一个项目)我会说:

  • 如果成员是不可变的(即const)或没有依赖的简单(如带有成员X和Y的点类),则不使用getter/setter .

  • 如果成员private只是它也可以跳过getter/setters.我也算内部的成员PIMPL -班如private如果在.cpp单元短小.

  • 如果成员是publicprotected(protected非常差public)和非const,非简单或具有依赖关系,那么使用getter/setter.

作为一个维护人员,我想要拥有getter/setter的主要原因是因为我有一个地方可以放置断点/记录/其他东西.

我更喜欢替代2的风格,因为它更易于搜索(编写可维护代码的关键组件).

  • 接受社区Wiki问题的特定答案总是有些奇怪,因为每个答案都可以帮助您。但是,我认为您的理由是最好的。我目前正在尝试尽可能避免使用getter / setter方法。提出替代方案需要花费一些时间,但它们通常会更好。如果我需要您所提到的简单数据,通常会使用仅数据结构。 (2认同)

Ash*_*ain 8

2)是最好的IMO,因为它使你的意图最清晰. set_amount(10)更有意义amount(10),并且作为一个好的副作用允许一个名为的成员amount.

公共变量通常是个坏主意,因为没有封装.假设您需要在更新变量时更新缓存或刷新窗口?如果您的变量是公开的,那就太糟糕了.如果您有set方法,可以在那里添加.

  • 规范封装意味着隐藏逻辑单元的内部状态和行为细节.如果您通过公共接口访问私有数据成员 - 那么您*已经*破坏封装,无论您是否使用访问器进行封装​​.封装好的类没有访问器:相反,它们具有以公开不可见的方式使用和影响内部状态的活动方法. (2认同)

Omn*_*ous 7

  1. 我从不使用这种风格.因为它可以限制您的类设计的未来,并且明确的geters或setter与良好的编译器一样有效.

    当然,实际上内联显式getter或setter会在类实现上创建同样多的底层依赖.这只是减少语义依赖.如果更改它们,仍然需要重新编译所有内容.

  2. 当我使用访问器方法时,这是我的默认样式.

  3. 这种风格对我来说太"聪明"了.我确实在极少数情况下使用它,但仅限于我真的希望访问者尽可能多地感受变量.

我认为有一个简单的变量包可能是一个构造函数的情况,以确保它们都被初始化为理智的东西.当我这样做时,我只是把它做成一个struct公开的.

  • +1为"太聪明".我建议不要滥用过载的可能性,它只会让读者更难,而且搜索代码库也更难. (3认同)

M. *_* E. 6

  1. 如果我们只想表示pure数据,这是一种很好的风格.

  2. 我不喜欢它:)因为get_/set_当我们可以在C++中重载它们时真的没必要.

  3. STL使用这种风格,例如std::streamString::strstd::ios_base::flags,除非应该避免!什么时候?当方法的名称与其他类型的名称冲突时,则使用get_/set_样式,例如std::string::get_allocator因为std::allocator.

  • 我担心STL可能在这方面有点不一致.可悲的是,Stroustrup本人似乎并没有对如何做吸气剂/制定者表达意见,只是他不喜欢与其中许多人的课程. (4认同)