Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Const-correctness with getters of vector of non-pointers

I have a quick question regarding const-correctness for getters of vector of non-pointers.

Basically, I have this class with a non-const getter and a const getter for m_Vertices:

class Mesh
{
public:
    std::vector<Vertex>& GetVertices() { return m_Vertices; }

    const std::vector<Vertex>& GetVertices() const { return m_Vertices; }

private:
    std::vector<Vertex> m_Vertices;
}

The non-const getter makes sense — the getter is non-const, we return a non-const reference to a vector of non-const Vertex instances.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The const getter in the other hand doesn’t makes sense to me. I’m questioning the const-correctness and whether I should just return a copy of the vector. The problem I see is that we return a const reference to a vector of non-const Vertex instances. So, the callee will have a const reference to m_Vertices, but will still be able to modify the Vertex instances, which feels wrong to me in terms of const-correctness.

In that case, should I simply return a copy of m_Vertices?

Thank you,

Anthony

>Solution :

First of all understand that this is an opinion-based question. There is no right or wrong answers when you are designing a class regarding the usage of const.

However, that said, in this case your const declarations are reasonable. In particular your statement "the callee will have a const reference to m_Vertices, but will still be able to modify the Vertex instances" is not true — because of the decisions that were made in the implementation of std::vector regarding const-ness.

There are three main ways someone might want to modify the vector and its elements. The callee may want to add/delete items from the vector, may want to change the value of a field of the elements, or may want to replace one of the elements. A reference to a const vector will make all three of those actions errors:

#include <iostream>
#include <vector>
#include <span>

struct point {
    double x;
    double y;
};

class vertices {
    std::vector<point> points_;
public:
    vertices(std::span<const point> pts) :
        points_{pts.begin(), pts.end()}
    {}

    const std::vector<point>& get() const {
        return points_;
    }

    std::vector<point>& get() {
        return points_;
    }
};

int main()
{
    vertices verts({{ {1.0,2.0}, {3.0,4.0}, {5.0,6.0} }});
    const auto& const_verts = verts;

    verts.get().push_back({ 7.0,8.0 }); // <= yes.
    //const_verts.get().push_back({ 7.0,8.0 }); <= no

    verts.get().front().x += 1; // <= yes.
    //const_verts.front().x += 1; // <= also no

    verts.get()[0] = { 0.0,0.0 }; // <= yes.
    //const_verts.get()[0] = { 0.0,0.0 }; <= no
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading