sop
sop

Reputation: 3625

How to get the size of a c++ class member vector?

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

Upvotes: 8

Views: 2744

Answers (3)

BartoszKP
BartoszKP

Reputation: 35891

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.

Upvotes: 15

Fsmv
Fsmv

Reputation: 1176

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.

Upvotes: 10

chris
chris

Reputation: 2621

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.

Upvotes: 5

Related Questions