Return reference to a vector member variable

Mam wektor jako członek w klasie i chcę zwrócić do niego odwołanie poprzez funkcję getVector (), aby móc go później zmodyfikować. Czy nie lepiej jest poćwiczyć funkcję getVector () jako const? Jednak w poniższym kodzie pojawił się błąd "qualifiers dropped in binding reference of type...". Co należy zmodyfikować?

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;
}
Author: arjacsoh, 2011-12-05

4 answers

Ponieważ jest to funkcja member const, zwracany typ nie może być referencją non-const. const:

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

Dlaczego jest w porządku? Ponieważ w const funkcji member, każdy element staje się const w taki sposób, że nie można go modyfikować, co oznacza, że myVector jest wektorem const w funkcji, dlatego musisz również wprowadzić Typ zwracający const, jeśli zwraca referencję.

Teraz nie możesz zmodyfikować ten sam obiekt. Zobacz co potrafisz, a czego nie:

 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
Przy okazji, zastanawiam się, dlaczego w ogóle potrzebujesz takiego.
 28
Author: Nawaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 11:52:42

Nie jest niczym niezwykłym deklarowanie zarówno wariantów const, jak i mutable, w ten sposób:

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

Podstawowy problem w twoim programie polega na tym, że zwracasz odniesienie nie-const z metody const.

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

Więc zrób to const używając tej formy:

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

I jeśli jest to metoda non-const lub klient posiada referencję non-const, możesz legalnie użyć metody non-const:

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

Na koniec możesz zwrócić wartość (w niektórych przypadkach):

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

Ponieważ Kopia nie wymaga mutacji i nie zapewnia ekspozycji na wewnętrzne dane.

Więc będziesz dość często deklarował oba warianty.

Wyniki deklarowania obu są następujące:

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

Więc wszystko działa ładnie(poza redundancją metod).

 13
Author: justin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 11:05:03

Funkcję getVector Można zadeklarować jako const. Zwraca referencję, która może zostać zmodyfikowana, więc podczas gdy rzeczywista funkcja nie modyfikuje niczego w klasie, wywołujący będzie mógł zmodyfikować wewnętrzne dane.

Zadeklarować jako:

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

Jeśli chcesz, aby funkcja zwracała wektor, którego nie można modyfikować, użyj modyfikatora const zarówno na wektorze, jak i Funkcji:

const std::vector<int>& getVector() const;
 2
Author: Some programmer dude,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 11:02:00

Powodem jest to, że funkcja member const powinna zwracać tylko referencje const. Dzieje się tak, ponieważ w funkcji const każdy element danych staje się stały.

Dlatego musisz zadeklarować getVector () w ten sposób:

std::vector<int> &VectorHolder::getVector() const;
 0
Author: Lev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-05 11:06:29