Когда лучше возвращать ссылку на константу в C ++? - PullRequest
1 голос
/ 14 июля 2020

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

Это не столько вопрос по конкретной проблеме, сколько поучительный вопрос.

Мы находимся в процессе перехода на современный C ++ с несколько рудиментарного уровня C, и мне и моему коллеге поручено наставлять группу других людей по C ++, поскольку мы довольно хорошо владеем этим языком.

У меня небольшой спор с указанным коллегой по этому поводу. Предлагаемый пример представляет собой простой класс:

class Cls
{
private:
    vector<int> vec;

public:

    Cls() { /* put 3 random values in vec */ }

    const vector<int>& getVec() {return vec; }
};

Мой аргумент из того факта, что:

  1. Ссылки должны использоваться как возвращаемые, так как вы не теряете время копирование вещей. Это прямое ускорение.

  2. Ссылки должны быть константными, поскольку если вы вернете только ссылку на vec, то любой может изменить ее, используя только геттер, что, очевидно, плохо. Следовательно, нам нужно вернуть const TYPE& для геттеров.

Мой коллега поддерживает просто возврат vector<int> и покончить с этим. Его аргументы:

  1. Это продвинутая концепция, которой не следует учить с самого начала. Сейчас мы можем просто возвращаться по значению из геттеров (и, таким образом, создавать копии) и переходить к ссылке позже, когда они смогут понять, что происходит за кулисами. (Мое мнение состоит в том, что, поскольку я считаю использование этого очень хорошей практикой, его следует обучать и применять с самого начала, чтобы люди привыкли к этому, а затем часть, где мы убедимся, что все действительно понимают, что означают ссылки на константы, может появиться позже поскольку у нас может не быть времени довести подопечных до уровня, на котором можно жонглировать ссылками.)

Итак, мои вопросы в основном следующие:

  1. Есть ли какие-нибудь статьи о хороших практиках в этом вопросе и о том, когда использовать в качестве возвращаемых значений константные ссылки вместо значений? .. есть ли стандарт или соглашение в отрасли для ответа на этот вопрос?

Ответы [ 2 ]

2 голосов
/ 14 июля 2020

Решение о том, когда возвращать по ссылке или по значению, является не просто вопросом производительности, это вопрос семантики кода (хотя производительность обычно имеет большое значение при кодировании на C ++).

Некоторые известные примеры возврата по ссылке:

  • a getter часто ожидается, что он вернет константную ссылку на фактический член, если только этот член не дешево копировать
  • , чтобы разрешить цепочку методов или операторов, возвращающую ссылку на текущий объект (*this)

Вопрос о том, когда возвращать по ссылке, фактически сводится к более широкому вопросу о как безопасно управлять сроком службы объекта. Основные рекомендации C ++ по срокам жизни объектов - хороший ресурс, которого следует придерживаться.

Если объект, на который делается ссылка, переживает вызов функции, то, как правило, безопасно вернуть его по ссылке.

Итак:

  • this, члены класса и объекты со статусом c продолжительность хранения: безопасно вернуть его по ссылке
  • локальные переменные и входные аргументы функции : небезопасно возвращать по ссылке

Что касается входных аргументов - это применимо даже к const ссылкам, поскольку они могут ссылаться на временные. Например:

std::string const& badFunc(std::string const& arg) {
   return arg; // not a good idea
}

    std::string const& x = badFunc("abc");
    // now x contains a dangling reference
0 голосов
/ 14 июля 2020

Прежде всего, вы должны подумать о том, чего вы хотите достичь. Вам действительно нужен доступ для создания самого экземпляра данных или копии приемлемы для вас. Если кулак, то другого выхода нет, то с помощью ссылки или указателя. Но имейте в виду, что возвращенная ссылка на константу не гарантирует, что указанный объект не изменится. Он только говорит, что вызывающий не может его изменить, но его можно изменить внутри объекта вызываемого.

...