假设我有一个类Foo
,其中包含一个bar_
状态的私有变量Foo
。如有必要,我可以为bar_
编写公共get / set方法。当然,我尽可能地避免这种情况来保持封装。
假设我有这些get / set方法,每当我必须在属于bar_
的方法中访问或修改Foo
时,我通常会直接对bar_
执行,而不是使用get / set方法,我用它来从类外部访问bar_
。除了关于直接访问变量的速度与调用方法的关注之外,我没有任何理由,但我怀疑如果get / set方法是内联定义的(它们是),它应该没有区别。这有什么不同吗? const
是否会在此发挥作用?
到目前为止,我没有遇到任何问题,但我有一种挥之不去的感觉,我做错了。没有做任何令人信服的论据吗?关于此的任何指导原则?
答案 0 :(得分:14)
我知道它接近于此,但我讨厌获取/设置方法。 厌恶他们。几乎从不写它们。
一般来说,一个类应该提供比直接更多的高级操作,并且只是简单地读取和修改内部状态变量,或者它应该偏离方式并像struct
那样行事。
即使我要写一个,我也几乎不会在里面使用它。它们的重点在于您可以在不影响客户的情况下更改事物的内部表示。在课堂上,它是你关心的内部表现! 如果您想在课堂上使用自己的界面对课程进行大量操作,那么您可能会有第二堂课在争取离开。
答案 1 :(得分:5)
除了关于直接访问变量的速度与调用方法的关注之外,我没有任何理由,但我怀疑如果get / set方法是内联定义的(它们是),它应该没有区别。这有什么不同吗? constness在这方面发挥了作用吗?
inline关键字在编译器是否进行任何内联时几乎不起作用。在这方面对关键字的使用基本上已被弃用。现代编译器内联就像疯了一样,他们知道什么时候可以更好地完成任何程序员。
任何值得污垢的编译器都会说“嗯,调用这个函数来获取这个成员变量;嘿,我可以得到成员变量!”你什么都不担心。无论是否有任何内联关键字,都会发生这种情况。
那就是说,我几乎总是使用成员函数。如果我改变变量在访问时的行为方式,我现在“自动”应用它在任何地方使用它。干净的代码应该是你的目标,但不是教条“总是跳过功能”。
任何时候我只想要一个变量值,我使用相应的成员变量。 (即,如果我写std::vector
,如果我需要检查尺寸是否小于某些东西,我会说size() < x
)。但是如果直接使用变量更清晰,那就改为使用,例如mSize++
。
const
- 这是无关紧要的。如果你处于非const函数中,你将使用getter的非const版本,与const相同。显然,使用成员直接维持const-ness。没有区别。
答案 2 :(得分:2)
最好使用get
和set
方法:它更干净,更好地维护DRY原则(仅进行一次验证),并允许子类覆盖方法并查看对所有更改的一致行为变量。
答案 3 :(得分:1)
这是一个意见问题,也是一个判断问题,但总的来说,Foo
方法的内部在你试图维护的封装内,因此他们访问是完全合理的。 bar_
直接。它们都在同一个位置,因此如果您更改类的内部表示以删除bar_
,您也可以轻松找到要更改的所有用途。
在大型类中内部使用get / set函数是有道理的,尤其是bar_
不是类的实现设计的关键部分,并且可以在不影响其余部分的情况下进行更改。但是,在许多情况下,如果您正在以bar_
不再存在并且计算其相应的get_bar()
的方式更改内部表示,您几乎肯定会想要重新审视内部用法以确定您是否想要重构它,以便它不进行计算或不同的计算。
话虽如此,速度并不是不这样做的理由 - 但太多层封装的可理解性成本是;除非是封装实际上简化代码的情况之一,否则四十行类不应该复杂化其他内部封装。
编辑:此外,ehdv提出了一个我错过的重要问题:如果您预期派生类会覆盖此内部表示的一部分,则使用get / set函数可以使覆盖更容易一致地执行。这可能是决定中的另一个因素。
答案 4 :(得分:1)
答案 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 _。