Getters and Setters for STL Containers – Best Practices

cgetterssettersstl

Consider I have a vector and map as class members:

class MyClass{
protected:
    std::vector<int> myVector;
    std::map<int,std::string> myMap;
};

Should the getter and setter access the container itself like this,

class Myclass{
public:
    std::vector<int>& getMyVector(){
        return this->myVector;
    }

    std::map<int,std::string>& getMyMap(){
        return this->myMap;
    }
protected:
    std::vector<int> myVector;
    std::map<int,std::string> myMap;
};

or access the elements inside the container like this:

class Myclass{
public:
    int getMyVectorAtIndex(int i){
        return this->myVector[i];
    }

    void setMyVectorAtIndex(int i,int v){
        this->myVector[i]=v;
    }

    std::string getMyMapByKey(int k){
        return this->myMap[k];
    }

    void setMyMapByKey(int k,std::string v){
        this->myMap[k]=v;
    }
protected:
    std::vector<int> myVector;
    std::map<int,std::string> myMap;
};

?

Best Answer

A class should encapsulate its state, which means abstracting over it.

In the first example, your members might as well be public, since returning references lets the user do absolutely anything with them anyway.

The second is harder to decide. The theoretical nature of your example means that I still don't like it; the names are meaningless, and I can't see what abstraction is provided by the class.

My point is that there can be no hard rule of "this is how you expose container members", because that would mean you're letting your interface be guided by the implementation, which is the wrong way to do it. What you need to think about is what interface makes sense for the class you're writing, and then you can decide how to implement it.