8

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()?

11
  • 1
    Personally I'd use the vector getter, but make it return a reference to avoid copying. Commented Aug 5, 2014 at 15:52
  • 5
    Do you like copying vectors around in order to get their size and then throw the copy away? Do you think this kind of activity puts your hard-earned gigaflops to good use? Perhaps copying the universe in order to count characters in a copy of this comment is a good design desicion? Commented Aug 5, 2014 at 15:56
  • 4
    @Fsmv Strongly disagree about that. Commented Aug 5, 2014 at 16:00
  • 3
    @Fsmv That refers to returning a local variable, not a class member. Commented Aug 5, 2014 at 16:04
  • 2
    @Fsmv Even if that were correct, "the compiler is so smart that it will make up for my stupidity" is no excuse for violating fundamental coding practices. Commented Aug 5, 2014 at 16:06

3 Answers 3

15

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Pretty much what I was trying to say, except much more nicely put :-)
+1 But my class is not containing just one vector and the geVectSize() is just in the "minimal code". I have just asking about the best practice. Your answer seems to be answer the question, but it is a little aggressive.
I don't see anything inappropriate about the language.
About the pants: "The cleaner needs the pants and the seller needs the money, so give the seller the money and the cleaner the pants!" That is it, right?
@sop Something like this. But the point is, not to reveal technical details to others, so they won't rely on them, so these details will be easy to change. In this case - the seller shouldn't need to know that you have your wallet in your pants, or even that you are wearing pants. Well, at this point of detail this analogy deteriorates a bit ;) I've added some more particular information on the flexibility part.
10

Make a "size getter" and return the value of m_myVec.size() unless you actually need complete access to the vector. The size getter would expose less of your code to the outside world. If you're just going to provide a method to get the vector it's essentially not private at all.

1 Comment

+1. Good encapsulation means not just hiding the vector, but even hiding the fact (aka. implementation detail) that there is a vector.
5

Well, first of all, as commenters have pointed out, IF you use a getter for the vector, make it return a const reference instead of a copy.

To answer your question: It depends on what level of data encapsulation you want. If the vector itself is an implementation detail of the class, and you do not want users of the class to be able to change its contents (or only through well defined operations in the class contract), you should not have a getter for (a reference to) the vector.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.