Я имею, идут очень простой вопрос, но к сожалению я не могу изобразить ответ сам.
Предположим, что у меня есть некоторая структура данных, которая содержит настройки и действия как карта настроек. У меня есть a 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);
Setter first:
SetValue
позволяет компилятору некоторые оптимизации, которые не могут быть сделаны при передаче по const-ссылке, это объясняется в статье Дейва Абрахамса, "Want Speed? Pass by Value."Setter
обычно лучше, потому что вы можете проверить устанавливаемое значение, тогда как при использовании простой ссылки у вас нет гарантии, что вызывающая сторона не сделает ничего глупого с данными. Для getter:
std::wstring
, потому что вам нужны некоторые настройки в UTF-8... Это зависит от использования. Должен ли GetValue ("foo") = "bar"
иметь смысл? В этом случае возврат по значению не дает того, что вы хотите.
Это очень "чувствительный" момент C++. IMHO это одна из самых слабых точек дизайна C++. AFAIK не существует действительно хорошего выбора, который будет и выглядеть, и работать хорошо.
Следует упомянуть, что оптимизация RVO обычно делает только часть работы. Без нее типичное выражение вроде этого:
std::string txt = GetValue("...");
будет фактически создавать 2 копии! Зависит от компилятора, но обычно оптимизация RVO устраняет только одну копию, однако вторая все равно остается.
Если вы можете вернуться по ссылке const, сделайте это. Единственная причина для возврата класса управления памятью, такого как std :: string, по значению, заключается в том, что это временная строка.