The idea of Object-Oriented Programming Based on C ++ (2)

Source: Internet
Author: User

We all know that,C ++The most important concept is class. After learning about the class, you can start to do some programming-advanced applications-design programs, instead of simply turning algorithms into code. To illustrate how to design a program, it is necessary to first understand whatObject-Oriented Programming. We recommend that you read this series of articles for your reference. Next to the previous article>

Object-Oriented Programming

The preceding description shows that the design program is the description of the problem to be solved. However, arguments can be expressed only by the concepts of nouns and verbs, and objects are exactly the realization of the concepts of nouns, instead, you can use the class without member variables mentioned above to map the "verb concept" to convert it into an object. Therefore, a world can be completely composed of objects, and only objects are represented in the world based on algorithms before subsequent code compilation, this programming method is called the object-oriented programming idea.

Note: first, design the world where the algorithm should be based, and then express it with all objects. Then design the algorithm and map it to the code. However, when writing a merchant's cross-river problem, the algorithm was provided directly, and the world was not designed? In fact, because the problem was too simple, I designed the world subconsciously and described it with the riverbank theory mentioned above. It should be noted that the design of the world is totally dependent on the problem. To be precise, I did not design the world, but designed the riverbank theory to describe the problem.

Next, because the object is an instance, it is a design class in C ++ to describe the world with the object, and a combination of the class instances will express the world. However, it should be noted that the object-oriented method describes the world, but it also describes the algorithm, because the algorithm will also propose some concepts that need to be mapped, such as the cross-river scheme in the algorithm of the previous merchant's cross-river problem.

But remember, when you describe an algorithm and perform operations on the class defined in the world, you must maintain the design of that class, do not map the algorithm to a member function of the class because the operations on the instance of the class in the algorithm are too complex, because this seriously masks the implementation of the algorithm, destroys the program architecture. For example, if an algorithm is used to keep the car in place and requires complex operations, is it necessary to add a function for the car to keep it in place ?! This is a frequent mistake when designing a class. For this reason, an object-oriented code is not just composed of classes, it may also map some operations in the algorithm into functions, and there are a large number of global functions.

Remember: when designing a class, if it is a concept mapped to the world, do not consider an algorithm, but design it with the world as the boundary, do not add incorrect members to an algorithm because of a specific need.

Therefore, the concept of nouns is mapped to a class. The attributes and states of the concept are mapped to member variables, and the functions of the concept of nouns are mapped to member functions. What should we do with "verb concept? Ing to a class without member variables? As we can see earlier, this is not a common practice. STL only uses it as a technique), so it is often mapped to a function, although this is based on object-oriented thinking, it is much easier to understand and the program architecture is much more concise.

With the advent of object-oriented programming, a new design method was born. Because it is so good that it is widely spread, but wrong understanding leads to wrong ideas born everywhere, and even worse, it is put before the horse, this design method is called object-oriented programming ideas, its name is encapsulation.

Encapsulation

First, let's take a look at the design of the following classes that can often be seen in the explanations of objects in various VC tutorials.

 
 
  1. class Person  
  2. privatechar m_Name[20]; unsigned long m_Age; bool m_Sex;  
  3. public:  const char* GetName() const;  void SetName( const char* );  
  4. unsigned long GetAge() constvoid SetAge( unsigned long );  
  5. bool GetSex() const;  void SetSex( bool );  
  6.   }; 

The above defines all member variables as private, and then provides three pairs of Get/Set functions to access the above three member variables because they are private and cannot be directly accessed from outside ), these three pairs of functions are all public. Why? These textbooks encapsulate the internal memory layout of class persons, in this way, the outside world does not know how the memory is laid out, and thus the validity of the memory can be ensured only by the class itself to operate its instance ).

First of all, we need to confirm the absurd design above. It makes no sense to be authentic and "Unlocked. Then let's look at the so-called memory layout encapsulation. Assume that the above statement is in Person. h, and then use the class Person in B. cpp, which would have to be # include "Person. h". replace it with the following:

 
 
  1. class Person  
  2. publicchar m_Name[20]; unsigned long m_Age; bool m_Sex;  
  3. publicconst char* GetName() const;  void SetName( const char* );  
  4. unsigned long GetAge() constvoid SetAge( unsigned long );  
  5. bool GetSex() const;  void SetSex( bool );  
  6.   }; 

Then use the class Person in B. cpp as usual, as shown below:

 
 
  1. Person a, b; a.m_Age = 20; b.GetSex(); 

Here, the Person: m_Age is used directly. Even if you do not do such a bad action, # include "Person. h" is still used, as follows:

 
 
  1. struct PERSON { char m_Name[20]; unsigned long m_Age; bool m_Sex; };  
  2. Person a, b; PERSON *pP = ( PERSON* )&a; pP->m_Age = 40; 

The member Person: m_Age of instance a whose Person is still directly modified above. How can I hide the memory layout ?! Recall the role of the Declaration. The memory layout of the class is required when the compiler generates an object. It cannot hide anything about the object implementation for any code that uses the object, otherwise, the compiler cannot compile the corresponding code.

In terms of semantics. The Person ing is not the concept of a Person in the real world. It should be the record buffer in the table that stores information about a Person in a database, so should the buffer have the functions represented by those three pairs of Get/Set? The buffer zone is used to buffer data. It is used by other operations After buffering, just like a box.

Therefore, the above three pairs of Get/Set do not have to exist, and the three member variables cannot be private. Of course, if the Person ing is not a buffer, and there are semantics as described above in other worlds, there is no problem with the definition as above, however, it would be a big mistake to define classes because of the encapsulation of the memory layout.

The error above is that it does not understand encapsulation. To demonstrate encapsulation, let's take a look at the MFCMicrosoft Foundation Class Library-Microsoft functional Class Library. A Library file that defines many classes, most of which are encapsulation designs. The definition of CFile class in library files described in SDK description.

It can be seen from the name that it maps to the file concept in the operating system, but it has such a member function-CFile: Open, CFile: Close, CFile :: read, CFile: Write. What's the problem? These four member functions map object operations rather than file functions, including opening a file, closing the file, reading data from the file, and writing data to the file. Isn't this the same as the semantics of the previously mentioned member functions?

The preceding four operations share a common nature. They are all operations applied to the file resource. They can be called "functions". For example, a file has the "opened" function, it has the "read" function, but note that they are not actually a file function.

According to the original statement, the FILE should be mapped into a structure, such as FILE. Then, the four operations above should be mapped into four functions, and the functions of namespace should be reused, as follows:

 
 
  1. namespace OFILE  
  2. {  
  3. bool Open( FILE&, … );  bool Close( FILE&, … );  
  4. bool Read( FILE&, … );  bool Write( FILE&, … );  

The above namespace OFILE indicates that all the four functions are FILE operations, but each of the four functions has a FILE & parameter. Recall that non-static member functions all have a hidden parameter this, so an amazing idea came into being.

Think of all the sets of operations on a certain resource as a resource and map it into a class. The object of this class is the operation on an object. This method is called encapsulation, the class is called a packaging class or an encapsulation class.

Obviously, the packaging class maps "operations on a certain resource" and is an abstract concept, that is, all the packaging class objects are stateless objects, which should be logically stateless objects, however, if there is a link between multiple operations, there may still be states, but its semantics also changes accordingly. For example, if you have another CFile: Flush member function that is used to refresh the buffer content, there will be at least one status-buffer, and you can also have a status record that has already called CFile: Write, if not, you do not need to refresh it ).

Now we should be able to understand the meaning of encapsulation. Encapsulates operations on a certain resource into a class. This packaging class maps not to a "noun concept" defined in the world ", it is an abstract concept defined by the "verb concept" or "operation on a certain concept" in the world. Since a packaging class encapsulates operations on a certain resource, the packaging class object must have an attribute to indicate the object to be operated. For CFile in MFC, CFile :: m_hFile member variable type is HANDLE), which is Read in the CFile: Read and CFile: Write before the main operation process of the packaging class object.

What are the benefits? Encapsulation provides a means to convert part of the "verb concept" in the world into objects, this makes the program architecture simpler. Multiple "verb concepts" are converted into a "noun concept", which reduces the number of "verb concepts") and tends to object-oriented programming ideas.

However, the packaging objects and encapsulated objects should be differentiated. The packaging object is only a shell, and the encapsulated object must be a stateful object, because the operation is to change the state of the resource. For CFile, The CFile instance is a packaging object, which maintains a kind of resource defined in the packaged object-file Kernel Object Windows operating system, which is characterized by a HANDLE instance) -- reference in CFile: m_hFile.

Therefore, the packaging objects are independent of the encapsulated objects. CFile a; in this case, the value of a. m_hFile is 0 or-1, indicating that the referenced object is invalid. Therefore, if a. Read (... ); Will fail, because the resources applied by the operation are invalid.

In this case, you should first call a. Open (... ) To bind a to a specific file kernel object, and call a. Close (... ); Will be unbound. Note CFile: After the Close call, only the binding is unbound. This does not mean that a has been destroyed, because a maps not a file kernel object, but a packaging object for file Kernel Object operations.

If you think about it, you will find that Tigers can eat rabbits and rabbits can be eaten, so here it should be that the tiger has a function to "eat rabbits" or multiple rabbit packaging classes to encapsulate the "eat rabbits" operation?

In fact, there is no problem. "Tigers eat rabbits" and "rabbits are eaten" are totally different operations. The former involves two types of resources, and the latter only involves one type of resources, therefore, the two can be implemented at the same time, depending on their semantics in the corresponding world. For the real world, it can be simply said that tigers have a "eat" function and can eat "meat", while animals inherit from "meat" and "autonomous initiative" in multiple ways, rabbits inherit from animals.

Here, there is a class called "autonomous initiative", which means that an animal is conscious and can act on its own. In C ++, it is represented by a class with a member function, indicating that a function can be operated, however, the Radio also has functions such as adjusting the station. Is it hard to say that the radio can also be operated by itself ?! This is the significance of the world-operation.

I hope this article will help you.

Related Article

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.