Возврат ссылки из постоянной функции - PullRequest
1 голос
/ 29 января 2009
#include "iostream"
#include "vector"

class ABC {

};

class VecTest {

  std::vector<ABC> vec;

  public:

  std::vector<ABC> & getVec() const { //Here it errors out
      return vec;
  }

};

Удаление const исправляет его, разве getVec не является константным методом. Так почему же это не разрешено?

Ответы [ 5 ]

10 голосов
/ 29 января 2009

Что вам, вероятно, следует сделать, это вернуть константную ссылку.

const std :: vector & getVec () const {return vec; }

Это не разрешено, потому что вы сказали, что getVec - это метод const, то есть метод не должен каким-либо образом изменять объект this . Возврат неконстантной ссылки, возможно, позволит изменить его объект, поэтому компилятор не разрешит этого.

4 голосов
/ 29 января 2009

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

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

Таким образом, метод const не может возвращать ссылку (потому что он позволяет косвенно изменять состояние объекта). Что вы можете сделать, это вернуть константную ссылку. Таким образом, предоставляя пользователю доступ к внутренним элементам, но поддерживая контракт с клиентом.

Пример:

class X
{
    int&       getX();       // get a reference to X
    int const& getX() const; // get a reference to X BUT the interface guarantees
                             // the object will not change state.
    private:
        int x;
}; 

Еще один способ взглянуть на это.
Если у вас есть объект const. Вам разрешено только разрешено вызывать методы const. Если, вызвав метод const, вы можете получить ссылку на внутренний член объекта, вы можете изменить его состояние. Это нарушило бы const (ness) исходного объекта.

2 голосов
/ 29 января 2009

Тип возврата getVec() должен быть const std::vector<ABC>&.

1 голос
/ 29 января 2009

Чтобы добавить к тому, что уже было сказано, когда вы делаете метод const, экземпляр объекта, который он получает (указатель this), по существу становится const. Помните, что когда вы возвращаете vec, вы возвращаете неявно this->vec:

return this->vec; // it's a const std::vector<ABC> since "this" is const

«Constness» нельзя убрать - если вы явно не уберете его с помощью const_cast<>.

// to illustrate what's happening when you're returning from the function
std::vector<ABC> &return = this->vec; // can't assign const to non-const!

Следовательно, ваш тип возвращаемого значения также должен быть постоянным:

const std::vector<ABC> &return = this->vec; // all is good
0 голосов
/ 29 января 2009

Чтобы добавить к тому, что сказал Рэй Хидаят , метод const имеет доступ только к членам класса. Вы пытаетесь вернуть неконстантную ссылку на константную переменную-член, поэтому она не работает.

Если вам действительно нужен доступ к изменяемой версии переменной-члена из функции const, вы можете объявить переменную mutable. Я бы не рекомендовал это.

...