tags:

views:

265

answers:

5
#include "iostream"
#include "vector"

class ABC {

};

class VecTest {

  std::vector<ABC> vec;

  public:

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

};

Removing the const fixes it , is it not the case that getVec is a constant method. So why is this not allowed?

+2  A: 

The return type of getVec() needs to be const std::vector<ABC>&.

Henk
+9  A: 

What you should probably be doing is returning a const reference.

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

It's not allowed because you've said getVec is a const method, meaning the method should not change the this object in any way. Returning a non-const reference would possibly allow its object to be changed, so the compiler doesn't allow it.

Ray Hidayat
+4  A: 

If a method is const then it is a guarantee to the the compiler that the state of the object can not be changed by calling the method.

If the method returns a reference to an internal member, then the user of the method can indirectly change the state of the object via the reference.

So in effect a const method can not return a reference (because it allows the state of the object to be changed indirectly). What you can do is return a const reference. Thus allowing the user access to internal members but maintaining the cosnt contract.

Example:

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

Another way to look at it.
If you have a const object. You are allowed only allowed to call const methods. If by calling a const method you can retrieve a reference to an internal member of the object you can alter its state. This would violate the const(ness) of the original object.

Martin York
A: 

To add to what Ray Hidayat said, a const method only has const access to the class members. You're trying to return a non-const reference to a const member variable, so it fails.

If you really really need to access a modifiable version of a member variable from a const function, you can declare the variable mutable. I wouldn't recommend it, though.

Mark Ransom
+1  A: 

To add to what's already been said, when you make a method const, the object instance that it gets (the this pointer) essentially becomes const. Keep in mind that when you're returning vec, you're implicitly returning this->vec:

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

"Constness" can't be taken away -- unless you explicitly take it away with a 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!

Therefore your return type also has to be const:

const std::vector<ABC> &return = this->vec; // all is good
Ates Goral