调用this-> get / this->设置方法与直接访问C ++中的成员变量

时间:2010-03-03 18:44:17

标签: c++

假设我有一个类Foo,其中包含一个bar_状态的私有变量Foo。如有必要,我可以为bar_编写公共get / set方法。当然,我尽可能地避免这种情况来保持封装。

假设我有这些get / set方法,每当我必须在属于bar_的方法中访问或修改Foo时,我通常会直接对bar_执行,而不是使用get / set方法,我用它来从类外部访问bar_。除了关于直接访问变量的速度与调用方法的关注之外,我没有任何理由,但我怀疑如果get / set方法是内联定义的(它们是),它应该没有区别。这有什么不同吗? const是否会在此发挥作用?

到目前为止,我没有遇到任何问题,但我有一种挥之不去的感觉,我做错了。没有做任何令人信服的论据吗?关于此的任何指导原则?

8 个答案:

答案 0 :(得分:14)

我知道它接近于此,但我讨厌获取/设置方法。 厌恶他们。几乎从不写它们。

一般来说,一个类应该提供比直接更多的高级操作,并且只是简单地读取和修改内部状态变量,或者它应该偏离方式并像struct那样行事。

即使我要写一个,我也几乎不会在里面使用它。它们的重点在于您可以在不影响客户的情况下更改事物的内部表示。在课堂上,它是你关心的内部表现! 如果您想在课堂上使用自己的界面对课程进行大量操作,那么您可能会有第二堂课在争取离开。

答案 1 :(得分:5)

  

除了关于直接访问变量的速度与调用方法的关注之外,我没有任何理由,但我怀疑如果get / set方法是内联定义的(它们是),它应该没有区别。这有什么不同吗? constness在这方面发挥了作用吗?

inline关键字在编译器是否进行任何内联时几乎不起作用。在这方面对关键字的使用基本上已被弃用。现代编译器内联就像疯了一样,他们知道什么时候可以更好地完成任何程序员。

任何值得污垢的编译器都会说“嗯,调用这个函数来获取这个成员变量;嘿,我可以得到成员变量!”你什么都不担心。无论是否有任何内联关键字,都会发生这种情况。

那就是说,我几乎总是使用成员函数。如果我改变变量在访问时的行为方式,我现在“自动”应用它在任何地方使用它。干净的代码应该是你的目标,但不是教条“总是跳过功能”。

任何时候我只想要一个变量值,我使用相应的成员变量。 (即,如果我写std::vector,如果我需要检查尺寸是否小于某些东西,我会说size() < x)。但是如果直接使用变量更清晰,那就改为使用,例如mSize++

const - 这是无关紧要的。如果你处于非const函数中,你将使用getter的非const版本,与const相同。显然,使用成员直接维持const-ness。没有区别。

答案 2 :(得分:2)

最好使用getset方法:它更干净,更好地维护DRY原则(仅进行一次验证),并允许子类覆盖方法并查看对所有更改的一致行为变量。

答案 3 :(得分:1)

这是一个意见问题,也是一个判断问题,但总的来说,Foo方法的内部在你试图维护的封装内,因此他们访问是完全合理的。 bar_直接。它们都在同一个位置,因此如果您更改类的内部表示以删除bar_,您也可以轻松找到要更改的所有用途。

在大型类中内部使用get / set函数是有道理的,尤其是bar_不是类的实现设计的关键部分,并且可以在不影响其余部分的情况下进行更改。但是,在许多情况下,如果您正在以bar_不再存在并且计算其相应的get_bar()的方式更改内部表示,您几乎肯定会想要重新审视内部用法以确定您是否想要重构它,以便它不进行计算或不同的计算。

话虽如此,速度并不是不这样做的理由 - 但太多层封装的可理解性成本是;除非是封装实际上简化代码的情况之一,否则四十行类不应该复杂化其他内部封装。

编辑:此外,ehdv提出了一个我错过的重要问题:如果您预期派生类会覆盖此内部表示的一部分,则使用get / set函数可以使覆盖更容易一致地执行。这可能是决定中的另一个因素。

答案 4 :(得分:1)

只有在必须由类维护的某种不变量,前提条件或后置条件时,才应该只需要获取/设置。如果值的修改在整个类的其余部分没有“连锁反应”,那么用户应该能够直接修改它。但是,如果更改该值将导致其他事情发生(例如,更改缓存大小可能会导致缓存项目被清除),则get / set是合适的。

答案 5 :(得分:0)

如果您的编译器完全执行任何内联,它将能够内联获取和设置在给定类中定义和使用的方法。 const与此无关,inline指令也没有太大区别。

我通常更喜欢使用我的get()set()方法,即使是在类定义中也是如此。通过在类定义之外使用它们,您可以获得所有相同的好处,并且没有速度惩罚。

答案 6 :(得分:0)

在我看来,没有适合所有情况的规则。有时,最好编写这些私有的set / get函数,有时它不是。

例如,如果所有get / set函数都是这样的:

void set(int n)
{
   member_n = n;
}
int get_n() const
{
  return member_n;
}

然后,实际上不需要这些功能!

在其他需要规范化值的情况下,您可以编写这些get / set函数。例如标准化角度:

void setAngle(int angle)
{
  member_angle = angle%two_PI;
}

答案 7 :(得分:0)

我更喜欢使用获取/设置功能。 因为我发现如果直接使用成员变量很难调试。 尤其是当您的班级很大并且有很多函数可以访问bar _。