始终返回成员变量getter的引用是一个好主意吗?

时间:2010-09-19 05:35:55

标签: c++ class getter member-variables

如果我的某个类包含许多intfloatenum成员变量,那么将它们作为引用而不是副本返回是一种有效和/或良好的做法,并返回常量引用,不应该进行任何更改?或者我有理由将它们作为副本归还吗?

7 个答案:

答案 0 :(得分:7)

没有理由通过引用返回基本类型,例如intfloat,除非您希望允许更改它们。通过引用返回它们实际上效率较低,因为它不会保存任何内容(int和指针通常具有相同的大小),而解除引用实际上会增加开销。

答案 1 :(得分:4)

如果它们是常量引用,也许就可以了。如果它们不是常量引用,可能不是。

关于效率 - 在64位机器上,引用将是64位数量(伪装指针); intfloat以及enum会更小。如果您返回引用,则表示您正在强制间接;它的效率较低。

因此,特别是对于内置类型作为返回值,通常最好返回值而不是引用。

答案 2 :(得分:4)

有些情况是必要的:

查看任何课程的重载operator[]。它通常有两个版本。变异版本必须返回引用。

int &operator[](int index);           // by reference
int operator[](int index) const;      // by value

一般情况下,允许某个类通过可信实体访问类成员是可以的。朋友。如果这些可信实体还需要修改状态,引用或指向类成员的指针,则是唯一的选项。

在许多情况下,引用通常会简化语法,例如'v'是STL向量。

v.at(1) = 2 vs *(v.at(1)) = 2;

答案 3 :(得分:1)

这可能主要是风格或偏好问题。不返回引用的一个原因是因为您使用getter和setter来允许您更改这些成员的实现,如果您将私有成员更改为其他类型,或者因为可以计算它而完全删除它,那么您不再拥有返回引用的能力,因为没有什么可引用的。

另一方面,返回非平凡类型(复合类)的引用可以使代码比复制更快一些,并且可以允许通过返回的引用(如果需要)分配这些成员。 / p>

答案 4 :(得分:0)

差不多,const引用更好。对于整数而言,这一点没有意义,因为你希望它们被改变,或者因为它们的大小(或几乎)与参考相同。

所以是的,这是一个好主意。我更喜欢另一种语言或者用我自己的C ++东西进行破解,只是让var公开(再一次只是我自己的东西)

答案 5 :(得分:0)

这是性能问题,但从稳健性的角度来看,我会说最好是返回值而不是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);
      }
   }  
}

因此,如果它具有语义意义,我们可以避免过多的动态分配,我更喜欢按值返回。

答案 6 :(得分:0)

吸气剂是针对类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后被复制。但编译器可以避免使用不必要的副本,请参阅Return Value Optimization