Let's say I have a container class called myList
. This container class has a private member variable called capacity
that holds the number of values in the instance.
It might be beneficial for users of the class to have access to capacity
for, say, knowing when they've reached the end while going through each value in a loop. Therefore, capacity
should be public.
However, that would also allow users of the class to modify capacity
, which would obviously screw things up.
myList myInstance;
myInstance.capacity = 123;
Would it be considered bad practice to have a public member function that just returns the value of capacity
, which would be a private variable? For example:
unsigned int getCapacity()
{
return capacity;
}
What about a "clone" variable that's updated to the value of capacity
whenever the value of capacity
changes? Users of the class would access the public "clone" rather than the private variable itself.
Have a capacity getter.
But mark it as a const member:
unsigned int getCapacity() const
{ //^^^^^^^
return capacity;
}
The second solution does not work.
As it is not reliable (one user may update it then the next user would get an invalid value when they read it).
Though you should consider if the user of your class really neads this information.
What can they do with it?
So you want to pre-allocate memeory if the capacity is not enough?
MyList x;
// I am going to add 10 items make sure there is enough room.
if (x.size() + 10 < x.capacity())
{ x.resize(x.size() + 10);
}
In this situation just always re-size. Then make your container do nothing if it aleady has the space.
x.resize(x.size() + 10); // If the container has enough space do nothing.
// Otherwise make sure there is enough room for 10 more items.
It is usually better for an object to manage it's self, rather than provide access to its internal state to allow other objects to manage it indirectly. Even though you are de-coupling the implementation from the actual variable you are still coupling yourself to the interface of having a capacity and it does not really provide you with a meaningful benefit.
So methods should (generally) be actions (verbs) that perform actions on the object. These actions manipulate the state of the object. Let the actions be the interface to your object. Note that once you define the interface to an object changing that interface (removing functionality) is very hard.