始终返回成员变量Geters的参考是个好主意吗?
-
04-10-2019 - |
题
如果我有很多课 int
, float
, , 和 enum
会员变量,将其作为参考而不是副本返回并返回不应进行任何更改的情况下返回常数引用吗?还是我应该将它们作为副本退还的原因?
解决方案
没有理由返回原始类型,例如 int
和 float
通过引用,除非您想允许它们更改。实际上,通过参考返回它们的效率较低,因为它没有节省(int
s和指针通常是相同的尺寸),而退化实际上会增加开销。
其他提示
如果它们是不变的参考,也许可以。如果它们不是恒定的参考,则可能不是。
至于效率 - 在64位机器上,参考文献将为64位数量(变相指针); int
和 float
和 enum
会更小。如果您返回参考,则强制一定的间接水平;效率较低。
因此,特别是对于内置类型作为返回值,通常最好返回值而不是参考。
某些情况有必要:
看超负荷 operator[]
对于任何班级。它通常有两个版本。突变版本必须返回参考。
int &operator[](int index); // by reference
int operator[](int index) const; // by value
通常,可以允许班级朋友通过可信赖的实体访问类成员。如果这些受信任的实体也需要修改状态,则是唯一的选择。
在许多情况下,参考通常会简化语法,例如“ v”为stl vector。
v.at(1) = 2 vs *(v.at(1)) = 2;
这可能主要是风格或偏好问题。不返回引用的原因之一是因为您使用的是getters和setter来允许您更改这些成员的实现,如果您将私人成员更改为另一种类型,或者完全将其删除,因为它可以计算,那么您将不再有返回参考的能力,因为没有参考。
另一方面,非平凡类型(复合类)的返回参考可以在制作副本上加快代码的速度,您可以允许通过返回的参考(如果需要)分配这些成员。
几乎,const引用更好。对于INT和此类毫无意义,因为您希望它们更改或因为它们的大小(或几乎)与参考相同。
所以是的,这是一个好主意。我更喜欢另一种语言或闯入我自己的C ++东西,只允许VAR公开(再次只是我自己的东西)
这主要是一个表演问题,但是从鲁棒性的角度来看,我会说最好是返回值而不是const引用。原因是甚至const引用削弱了封装。考虑一下:
struct SomeClass
{
std::vector<int> const & SomeInts () const;
void AddAnInt (int i); // Adds an integer to the vector of ints.
private:
std::vector<int> m_someInts;
};
bool ShouldIAddThisInt(int i);
void F (SomeClass & sc)
{
auto someInts = sc.SomeInts ();
auto end = someInts.end ();
for (auto iter = someInts.begin (); iter != end; ++iter)
{
if (ShouldIAddThisInt(*iter))
{
// oops invalidates the iterators
sc.AddAnInt (*iter);
}
}
}
因此,如果它具有语义上的意义,我们可以避免过度的动态分配,我更喜欢按价值返回。
Getters是为了排放班的说法 Exhaust Car.emit()
, ,汽车刚刚创造了 Exhaust
.
如果你一定要写 const Seat& Car.get_front_seat()
以后坐在 Driver
, ,您可以立即注意到有问题。
纠正,你宁愿写 Car.get_in_driver(Driver)
然后直接打电话 seat.sit_into(Driver)
.
第二种方法很容易避免您的尴尬情况 get_front_seat
但是门是关闭的,您实际上是通过封闭的门推入驾驶员。记住,您只要求座位! :)
总而言之: 始终按价值返回 (并依靠返回值优化),或意识到是时候改变设计了。
背景:创建类,以便可以将数据与其访问器功能,本地化错误等结合在一起。因此,类绝不是活动,而是面向数据的。
进一步的陷阱: 在C ++中,如果您由Const Ref返回某些内容,那么您可以轻松地忘记它只是参考,一旦对象被破坏,您就可以将其留下无效的参考。否则,该对象 将被复制 一旦它离开了Getter。但是不必要的副本是由编译器避免的,请参阅 返回值优化.