getters 应该通过引用还是通过值返回小的、琐碎的数据成员?

问题描述 投票:0回答:7

如果我有一个包含许多

int
float
enum
数据成员的类,将它们作为引用而不是副本返回,并返回不应更改的常量引用是否被认为是有效和/或良好的做法是制作出来的,还是有理由我应该将它们作为副本退回?

c++ class getter member-variables
7个回答
8
投票

没有理由通过引用返回诸如

int
float
之类的基本类型,除非您希望允许更改它们。通过引用返回它们实际上效率较低,因为它不会节省任何内容(
int
和指针通常大小相同),而取消引用实际上会增加开销。


4
投票

如果它们是持续引用,也许就可以了。如果它们不是持续引用,可能不会。

关于效率 - 在 64 位机器上,引用将是 64 位数量(变相的指针);

int
float
enum
会更小。如果你返回一个引用,你就强制了一定程度的间接;效率较低。

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


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;

1
投票

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

另一方面,返回非平凡类型(复合类)的引用可以比制作副本稍微加快代码速度,并且您可以允许通过返回的引用分配这些成员(如果需要)。


0
投票

几乎,const 引用更好。对于整数之类的没有意义,因为您希望更改它们或者因为它们与参考的大小相同(或接近)。

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


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);
      }
   }  
}

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


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,它就会被复制。但编译器会避免不必要的复制,请参阅返回值优化

© www.soinside.com 2019 - 2024. All rights reserved.