Это хорошая идея, чтобы всегда вернуть ссылки на переменные членов Getter?

StackOverflow https://stackoverflow.com/questions/3744635

Вопрос

Если у меня есть класс, который имеет много int, float, а также enum Переменные-члены, считается, что это считается эффективной и / или хорошей практикой, чтобы вернуть их в качестве ссылок, а не копии, и вернуть постоянные ссылки, где никакие изменения не должны быть сделаны? Или есть причина, по которой я должен вернуть их как копии?

Это было полезно?

Решение

Нет причин возвращать примитивные типы, такие как int а также float по ссылке, если вы не хотите, чтобы они были изменены. Возвращая их посредством ссылки на самом деле менее эффективна, потому что она ничего не спасает (intS и указатели, как правило, такие же размер), в то время как разрабатывание на самом деле добавляет накладные расходы.

Другие советы

Если они постоянные ссылки, возможно, это нормально. Если они не постоянные ссылки, вероятно, нет.

Что касается эффективности - на 64-битной машине, ссылки будут 64-битные количества (указатели в маскировке); int а также float а также enum будет меньше. Если вы вернете ссылку, вы заставляете уровень косвествия; Это менее эффективно.

Таким образом, особенно для встроенных типов в качестве возвращаемых значений, обычно лучше вернуть значение, а не ссылку.

Некоторые случаи необходимо:

Посмотрите на перегруженное 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;

Это, вероятно, в основном вопрос стиля или предпочтения. Одна из причин для не возвратных ссылок заключается в том, что вы используете GetTers и Setters, чтобы позволить вам изменить реализацию этих членов, если вы изменили частный член другому типу или полностью удалили его, потому что он может быть вычислен, то у вас больше нет Возможность возвращать ссылку, поскольку нечего ссылаться.

С другой стороны, возвращающиеся ссылки на нетривиальные типы (составные классы) могут немного ускорить свой код, создавая копию, и вы можете позволить тем членам назначаться через возвращенную ссылку (при желании).

Почти почти, Const ссылки лучше. Для INTS и таких Theres нет смысла, потому что вы хотели бы, чтобы они были изменены или потому, что они одинаковы (или почти) в качестве ссылки.

Так что да, это хорошая идея. Я предпочитаю другой язык или взломать на мои собственные вещи 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);
      }
   }  
}

Таким образом, если это делает семантически смысл, и мы можем избежать чрезмерных динамических распределений, я предпочитаю возврат по значению.

Геттерс для выбросов класса говорят Exhaust Car.emit(), где машина только что создала Exhaust.

Если вы обязаны написать const Seat& Car.get_front_seat()
позже сидеть в Driver, вы можете сразу заметить, что что-то не так.
Коррекольно, вы бы предпочли писать Car.get_in_driver(Driver)
который затем звонит напрямую seat.sit_into(Driver).

Этот второй метод легко избегает этих неловких ситуаций, когда вы get_front_seat Но дверь закрыта, и вы практически вытесните водителя через закрытую дверь. Помните, вы просили только сиденье! :)

В общем: Всегда возвращайте по значению (и полагаться на оптимизацию возврата Value), или осознайте время изменения вашего дизайна.

Фон: классы были созданы, так что данные могут быть соединены вместе со своими функциональными возможностями доступа, локализация ошибок и т. Д. Таким образом, классы никогда не являются активностью, но ориентированы на данные.

Дальнейшие подводные камни: В C ++, если вы вернетесь к Const Ref, то вы можете легко забыть, что это только Ref, и как только ваш объект разрушится, вы можете оставить недействительным Ref. В противном случае этот объект будет скопирован Как только это покидает добыча в любом случае. Но ненужденные копии избегают компилятора, см. Оптимизация возврата стоимости.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top