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

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

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

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

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

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

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

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

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

#Q

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

6
задан James McNellis 16 July 2010 в 23:27
поделиться

4 ответа

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

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

Setter first:

  • Передача по значению в SetValue позволяет компилятору некоторые оптимизации, которые не могут быть сделаны при передаче по const-ссылке, это объясняется в статье Дейва Абрахамса, "Want Speed? Pass by Value."
  • Использование Setter обычно лучше, потому что вы можете проверить устанавливаемое значение, тогда как при использовании простой ссылки у вас нет гарантии, что вызывающая сторона не сделает ничего глупого с данными.

Для getter:

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

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

6
ответ дан 8 December 2019 в 15:59
поделиться

Это очень "чувствительный" момент C++. IMHO это одна из самых слабых точек дизайна C++. AFAIK не существует действительно хорошего выбора, который будет и выглядеть, и работать хорошо.

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

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

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

1
ответ дан 8 December 2019 в 15:59
поделиться

Если вы можете вернуться по ссылке const, сделайте это. Единственная причина для возврата класса управления памятью, такого как std :: string, по значению, заключается в том, что это временная строка.

2
ответ дан 8 December 2019 в 15:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: