Terms 20: Avoiding a Public Interface Data Member
First, look at this problem from the perspective of "consistency". If the PUBLIC interface is a function, users do not need to catch their heads every time the member of the class: Is it necessary to use parentheses? - The use of parentheses is! Because each member is a function. In a lifetime, this can avoid how many times you caught your head!
Don't buy "consistent" account? Then you have to admit that the function can more accurately control the right to access the access to the data. If you make the data member as public, everyone can read and write it; if you use a function to get or set it, you can achieve a variety of controls such as access, read-only access, and read and write access. Even if you are willing, you can also only write access:
Class AccessLevels {public: int getReadOnly () const {returnemi;}
Void setReadwrite (int value) {readwrite = value;} int getReadwrite () const {returnem
Void setwriteonly (int value) {writeonly = value;}
Private: int noaccess; // Prohibits access this INT
Int readonly; // can read this int
Int readwrite; // can read / write this int
Int writeonly; // can write only this int};
Haven't persuaded you yet? That had to move out this heavy cannon: Functional Abstract. If you use a function to enable access to data members, you may use a period of calculation to replace this data member, but users who use this class have not known.
For example, it is assumed to write an application for detecting a car driving speed with an automated instrument. When each car is running, the calculated speed value is added to a collection of all current automotive speed data:
Class SpeedDataCollection {public: Void AddValue (INT Speed); // Add new speed value
Double averatesofar () const; // Return the average speed};
Now consider how to implement a member function averatesofar (see also the Terms M18). One method is to use a data member of the class to save the run average of all currently collected speed data. As long as the AVERAGESOFAR is called, the value of this data member is returned. Another different approach is to calculate the results by checking all the data values in the collection at a time called. (More comprehensive discussion on these two methods see clauses M17 and M18.)
The first method - hold a run value - makes each SpeedDataCollection object, because the space must be assigned a space for the data member that must be saved. But the averatesofar is very efficient: it can be an inline function that only returns a data member value (see Terms 33). In contrast, the average value is calculated each time the call makes the averatesofar slower, but each SpeedDataColection object is smaller.
Who can say which method is better? In a very tight machine in the memory, or in applications that are not frequently needed, each calculation average is a good solution. In applications that frequently require average, the speed is the most fundamental, memory is not a major problem, and the method of maintaining a run value is more preferable. Important, use member functions to access the average, you can use any way, it has great value flexibility, which is the scheme that contains average data members in the public interface. Therefore, the conclusion is that in the public interface, it is not far from searching for trouble, so it is necessary to safely hide the data after the high wall with the functional separation. If you start now, then we can exchange consistency and accurate access control without any cost.