Reading Notes Objective c ++ Item 22: declare data members as private, paitiveprivate

Source: Internet
Author: User

Reading Notes Objective c ++ Item 22: declare data members as private, paitiveprivate

First, let's take a look at why data members should not be public. Then we will see that the arguments applied to public data members are also applicable to protected members. Finally, we can conclude that the data members should be private.

1. Why cannot data members be public?

Why cannot data members be public?

2.1 consistency

Let's start with syntactic consistency (Item 18 ). If the data member is not Public, the only way the customer accesses the object is through the member function. If all the public interfaces are functions, you do not have to remember whether to use parentheses when accessing a class member. This facilitates the customer's use.

2.2 precise access control over data members

If consistency does not convince you, can you use functions to control access to data members more accurately? If you declare a data member as public, everyone has the read and write permissions on it, but if you use a function to get or set the value ), you can achieve no access, read-only and read-write access. If you need it, you can even implement write-only access:

 1 class AccessLevels { 2  3 public: 4  5 ... 6  7 int getReadOnly() const { return readOnly; } 8  9 void setReadWrite(int value) { readWrite = value; }10 11 int getReadWrite() const { return readWrite; }12 13 void setWriteOnly(int value) { writeOnly = value; }14 15 private:16 17 int noAccess; // no access to this int18 19 int readOnly; // read-only access to this int20 21 int readWrite; // read-write access to this int22 23 int writeOnly; // write-only access to this int24 25 };

 

This fine-grained access control is very important because many data members should be hidden. In rare cases, all data members must have a getter and a setter.

2.3 Encapsulation

Still unconvincing? It's time to launch the killer:Encapsulation. If you use a function to access a data member, you may use computing to replace the data member in the future. Any customers who use your class will not notice the changes of the class.

For example, if you are implementing an application, the automation device uses this application to record the speed of a vehicle. When each vehicle passes, the speed is calculated and the result is saved in a data set, which records all the speed data collected so far:

 1 class SpeedDataCollection { 2  3 ... 4  5 public: 6  7 void addValue(int speed); // add a new data value 8  9 double averageSoFar() const; // return average speed10 11 ...12 13 };

 

Now we need to consider the implementation of the member function averageSoFar. One way is to define a data member in the class to represent the average value of all the speed data so far. When averageSoFar is called, it only returns the value of this data member. Another method is to re-calculate the average value every time averageSoFar is called, which can be done by checking each data value in the dataset.

The first method is to increase the size of each SpeedDataCollection object, because you must allocate space for the average storage speed, total accumulation, and number of data points. However, averageSoFar can be effectively implemented; it is just an inline function that returns the average speed (see Item 30 ). On the contrary, calculating the average value during the request will make averageSoFar run very slowly, but each SpeedDataCollection object will be relatively small.

Who can determine which is better? On a machine with tight memory, and the average value is not frequently required in applications, it may be a better choice to calculate the average value each time. In an application that requires frequent average values, the speed is very important, but the memory is sufficient. You may prefer to save the average speed as a data member. The important thing here is to use a member function to access the average value (that is, encapsulate it). You can switch back and forth between these different implementations, you only need to re-compile the client. (Using the technology described in Item31, you don't even need to recompile it)

Hiding data members behind the function interface provides different types of implementations flexibly. For example, it can make the following implementation very simple: when the data member is read or written, it notifies other objects; the immutability of the verification class and the prefix and postcondition of the function; execute synchronization in a multi-threaded environment. Programmers who transfer data from other languages (such as Delphi and C #) to C ++ will recognize that the function of C ++ is equivalent to the "attribute" in other languages, however, an additional pair of parentheses is required.

Encapsulation is more important than it seems at first. If you hide your data members (that is, encapsulate them) to the customer, you can ensure that the class remains unchanged, because only the member functions can affect them. Further, you reserve the right to change your decisions in the future. If you do not hide these decisions, you will soon find that, even if you have a class source code, your ability to modify public members is limited, because if you modify public members, too many Customer Code will be damaged. Public means that this is not encapsulated. In reality, unencapsulated means that this cannot be changed, especially for widely used classes. Therefore, classes that are widely used need to be encapsulated because they most benefit from replacing an implementation with a better implementation.

2. Why cannot data members be protected?

The above arguments are similar for protected data members. In fact, they are exactly the same, although not at first. When the data member cannot be public, the reasons for syntactic consistency and fine-grained access control also apply to protected members, but what about encapsulation? Are protected data members more encapsulated than public data members? The surprising answer is that they are not.

Item 23 explains encapsulation. The number of code corruption that may result from a change in something is inversely proportional. The encapsulation type of a data member is inversely proportional to the number of code that may be damaged due to changes in the data member. For example, if the data member is removed from the class. (It may be replaced by a calculation, as implemented in averageSoFar ).

Suppose we have a public data member and we delete it. How much code will be destroyed? All the customer code that uses it will be destroyed. Generally, this should be an unknown number. Public Data members are not encapsulated at all. But if we have a protected data member, we will delete it. How much code will be destroyed now? All Derived classes that use it. Similarly, this is an unknown number of codes. The Protected data member is not encapsulated like the public data member, because in both cases, if the data member is modified, an unknown number of customer codes will be damaged. This is an intuitive violation, but an experienced library implementer will tell you that this is true. Once you declare a data member as public or protected and the customer starts to use it, it is difficult to change anything of the data member. Because once modified, too much code will be re-implemented, re-tested, re-edited, and re-compiled. From the encapsulation perspective, there are actually only two access levels: private (providing encapsulation) and other (not providing encapsulation ).

3. Summary
  • Declare the data member as private. It provides users with access to syntactically consistent data, fine-grained access control, immutability of execution classes, and implementation flexibility for class authors.
  • Protected is not more encapsulated than public.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.