Подтвердить что ты не робот

Возвратить ссылку на переменную-член вектора

У меня есть вектор как член в классе, и я хочу вернуть ссылку на него через функцию getVector(), чтобы иметь возможность модифицировать ее позже. Разве лучше не использовать функцию getVector() как const? Тем не менее, я получил ошибку "квалификаторы, сброшенные в ссылке привязки типа..." в следующем коде. Что нужно изменить?

class VectorHolder
{
public:
VectorHolder(const std::vector<int>&);
std::vector<int>& getVector() const;

private:
std::vector<int> myVector;

};

std::vector<int> &VectorHolder::getVector() const
{
return myVector;
}
4b9b3361

Ответ 1

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

const std::vector<int> &VectorHolder::getVector() const
{
   return myVector;
}

Теперь все в порядке.

Почему все нормально? Поскольку в функции-члене const каждый член становится const таким образом, что его нельзя изменить, что означает, что myVector является вектором const в функции, поэтому вам нужно сделать тип возврата const, если он возвращает ссылку.

Теперь вы не можете изменить один и тот же объект. Посмотрите, что вы можете сделать, а что нет:

 std::vector<int> & a = x.getVector();       //error - at compile time!

 const std::vector<int> & a = x.getVector(); //ok
 a.push_back(10);                            //error - at compile time!

 std::vector<int>  a = x.getVector();        //ok
 a.push_back(10);                            //ok

Кстати, мне интересно, зачем вам это нужно VectorHolder.

Ответ 2

это не редкость объявлять как const, так и изменчивые варианты, например:

std::vector<int>& VectorHolder::getVector() {
  return myVector;
}
const std::vector<int>& VectorHolder::getVector() const {
  return myVector;
}

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

std::vector<int>& VectorHolder::getVector() const {
  return myVector; // << error: return mutable reference from const method
}

поэтому вы создаете константу, используя эту форму:

const std::vector<int>& VectorHolder::getVector() const {
  return myVector; // << ok
}

и когда это находится в методе non const или клиент содержит неконстантную ссылку, то вы можете юридически использовать метод non-const:

std::vector<int>& VectorHolder::getVector() {
  return myVector; // << ok
}

наконец, вы можете вернуть значение (в некоторых случаях):

std::vector<int> VectorHolder::getVector() const {
  return myVector; // << ok
}

потому что копия не требует мутации и не подвергает воздействию внутренних данных.

чтобы вы в конечном итоге объявляли оба варианта довольно часто.

результаты объявления обоих:

VectorHolder m;
const VectorHolder c;

m.getVector().size(); // << ok
c.getVector().size(); // << ok - no mutation

m.getVector().push_back(a); // << ok
c.getVector().push_back(a); // << error: attempt to mutate const reference because the const vector is returned

так что все это хорошо работает (кроме избыточности методов).

Ответ 3

Функция getVector может быть объявлена ​​как const. Он возвращает ссылку, которая может быть изменена, поэтому, пока фактическая функция ничего не изменяет в классе, вызывающий может изменять внутренние данные.

Объявите его как:

std::vector<int>& getVector();

Если вы хотите, чтобы функция возвращала вектор, который не может быть изменен, используйте модификатор const как для вектора, так и для функции:

const std::vector<int>& getVector() const;

Ответ 4

Причина в том, что функция-член const должна возвращать только ссылки const. Это связано с тем, что в функции const каждый член данных становится постоянным.

Поэтому вы должны объявить getVector() следующим образом:

std::vector<int> &VectorHolder::getVector() const;