简体   繁体   中英

Return reference to a vector member variable

I have a vector as member in a class and I want to return a reference to it through a getVector() function, so as to be able to modify it later. Isn't it better practice the function getVector() to be const? However I got an error “qualifiers dropped in binding reference of type…” in the following code. What should be modified?

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

Since it is a const member function, the return type cannot be non-const reference. Make it const :

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

Now it is okay.

Why is it fine? Because in a const member function, the every member becomes const in such a way that it cannot be modified, which means myVector is a const vector in the function, that is why you have to make the return type const as well, if it returns the reference .

Now you cannot modify the same object. See what you can do and what cannot:

 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

By the way, I'm wondering why you need such VectorHolder in the first place.

it's not unusual to declare both const and mutable variants, like so:

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

the underlying problem with your program is that you return a non-const reference from a const method.

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

so you make it const using this form:

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

and when this is in a non const method or the client holds a non-const reference, then you can legally use a non-const method:

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

finally, you could return a value (in some cases):

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

because the copy requires no mutation and provides no exposure to the internal data.

so you will end up declaring both variants quite often.

the results of declaring both are:

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

so it all works out nicely (apart from the redundancy of the methods).

The function getVector can be declared as const . It returns a reference that can be modified, so while the actual function doesn't modify anything in the class, the caller will be able to modify internal data.

Declare it as:

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

If you want a function to return a vector that can't be modified, the use the const modifier on both the vector and the function:

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

The reason is that a const member function should only return const references. This is because in a const function, every data member becomes constant.

Therefore you have to declare the getVector() this way:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM