C ++ Получить метод - возвращение по значению или по ссылке

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

Вопрос

Я прошел очень простой вопрос, но, к сожалению, я не могу понять ответ сам.

Предположим, у меня есть некоторая структура данных, которая удерживает настройки и действует как карта настроек. у меня есть GetValue(const std::string& name) Метод, который возвращает соответствующее значение.

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

std::string GetValue(const std::string& name) const

и вернуть копию объекта и полагаться на RVO в производительности.

Другой будет означать изготовление двух методов

std::string& GetValue(...)
const std::string& GetValue(...) const

Что обычно означает дублирующий код или использование некоторых злых точек, чтобы использовать один из этих процедур дважды.

#Q.

Какой был бы ваш выбор в такой ситуации и почему?

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

Решение

На самом деле я бы, вероятно, использовал:

std::string GetValue(const std::string& name) const;
// or
const std::string* GetValue(const std::string& name) const;

void SetValue(std::string name, std::string value);

Сеттер первым:

  • Прохождение по значению в SetValue Позволяет компилятору несколько оптимизаций, которые не могут быть сделаны с проходом Const-Reference, это было объяснено в статье Дейва Абрахама, «Хотите скорость? Пройти по значению».
  • С помощью Setter Обычно лучше, потому что вы можете проверить набор значений, тогда как с простой ссылкой, у вас нет гарантии, что вызывающий абонент не сделает ничего глупо с данными.

Для Getter:

  • Вернувшись к копии кажется отходом с большинства раз, когда вы не будете изменять возвращенный объект (для карты настроек), однако указатель или ссылка подразумевают, что название объекта будет жить достаточно долго, если вы не можете гарантировать его, то точка Муот: возврат по значению. Также скопируйте позволяют избегать воздействия внутренней детализации, например, если вы внезапно переключиться на std::wstring Потому что вам нужны некоторые настройки в UTF-8 ...
  • Если вам нужна производительность, то вы готовы сделать некоторые уступки в этом отделе. Однако ссылка не позволяет вам сигнализировать о отсутствии свойства (если у вас есть некоторое волшебное значение), когда указатель делает его простым (NULL уже вырезан для вас).

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

Это зависит от использования. Должен GetValue("foo") = "bar" иметь смысл? В этом случае возврат по значению не делает то, что вы хотите.

Если вы можете вернуться на Const Reference, сделайте. Единственная причина возвращения класса управления памятью, как STD :: String по значению, это потому, что это временная строка.

Это очень «чувствительная» точка C ++. ИМХО Это одна из самых слабых точек дизайна C ++. AFAIK Нет действительно хорошего выбора, который будет оба выглядеть и хорошо выполнять.

Один момент, который следует отметить, что оптимизация RVO обычно делает только часть задания. Без этого типичное выражение, как это:

std::string txt = GetValue("...");

На самом деле будет производить 2 экземпляра! Зависит от компилятора, но обычно оптимизация RVO устраняет только одну копию, однако другой все еще там.

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