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;
}
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.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).
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;
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;
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