I have a class that has a member of type std::vector
. In some places I need the size of that vector in another class. Because the member is private, I have created a getter to return it. When reviewing the code a question came out in my mind: Is it better to call the getter and then it's size()
or is it good to create a "size getter" instead?
Here is my class:
class MyClass
{
private:
std::vector< int > m_myVec;
public:
std::vector< int > getMyVec() const { return m_myVec; }
// Shall I create:
// std::size_t getMyVecSize() const { return m_myVec.size(); }
// ... other function
};
In some other part of the code I do:
std::size_t sz = myClsObj.getMyVec().size(); // or
if (myClsObj.getMyVec().size() > 5) { /*...*/ }
Is it a good practice to do so, or I shall create and call the "size getter" instead?
I need both the vector (in other parts of the code I call the getter) and its size; so there is no point to choose to keep just one of the getters.
Another fact is that I am using C++11, so there is no need to return a const reference.
Based on the C++11: Is it so smart not to return the vector but its size if I call myClsObj.getMyVec().size()
?
You can refer to the Tell Don't Ask principle. It may be a bit confusing here, as both version are technically "asking" for something. But the point is not to use getters to retrieve implementation details of a class and then perform some operations on it, but to tell the class to do the required work, which is in this case - retrieving the size.
This is also related to the Law of Demeter. The approach with returning the whole vector is visualized in this link in an awesome way, with the following story:
[...] “that’ll be $1.95.” At this point, naturally, I removed my pants and the guy started screaming at me about police and indecent exposure. Confused, I said, “look, I’m just trying to pay you — I’ll hand you my pants and you go rummaging around in my pockets until you find my wallet, which you’ll take out and go looking through for cash.
The "size getter" method relates to a more natural way, of getting your wallet yourself from your pants and paying :-)
It is also comes directly from one of the most basic concepts in OOP - Encapsulation. Briefly, its point is to hide (encapsulate) as much details of class's implementation from the outside world. Less coupling gives you more flexibility in the future. Don't worry if this sounds too abstract or hazy. Every programmer (i.e. almost every programmer I've met, including me) eventually came to a point, when each supposedly simple change, had to be followed by an avalanche of fixes in distant parts of code. Felling the revenge of coupling under your fingers makes you recall this rule, and remember it forever ;)
And finally, usually you don't create classes that represent a wrapped vector or something similar. vector is just a technicality. Usually such a class represents a collection of some particular elements that have name on the level of your Domain logic. So most of the time it's not .getTheSizeOfMyInnerVector
but rather .getRecordCount
or .getNumberOfStudents
etc. Clients of such classes don't even need to know that there is a std::vector
inside. It doesn't matter, as long as the class handles its task for maintaining a collection of something. The aforementioned flexibility can for example mean in this case, that you can switch to a different container without worrying about the clients of your class. And without riffling through possibly thousands of places where this class is being used in your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With