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
, whi开发者_开发百科ch 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.
The accessor is a good solution. This is the one choosen by the STL. See std::vector::capacity(), std::vector::size(), ...
The first solution you describe is known as a getter, and it is considered good practice to have these.
The second solution is not actually a solution, it merely adds a second variable and introduces the necessity to update it.
No that would not be a bad practice. In fact using getters and setters is considered a best practice.
not a bad practice at all, thats how you need to do this actually.
If you have a public getter, you can just return a copy of, or const reference to capacity.
That will allow client's to see but not modify the data.
As long as you return the private
member by value or a const pointer instead of its address through non-const pointer you will be fine.
精彩评论