Return reference to a vector member variable

后端 未结 4 1890
日久生厌
日久生厌 2021-01-30 07:05

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 fun

相关标签:
4条回答
  • 2021-01-30 07:24

    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.

    0 讨论(0)
  • 2021-01-30 07:29

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

    0 讨论(0)
  • 2021-01-30 07:33

    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;
    
    0 讨论(0)
  • 2021-01-30 07:40

    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;
    
    0 讨论(0)
提交回复
热议问题