C ++ starts from scratch (11) (bottom) -- knowledge about classes

Source: Internet
Author: User

C ++ starts from scratch (11) (bottom) -- original source of knowledge about classes: Network

The middle part of this article has already introduced the meaning of virtual reality, that is, indirect acquisition, and examples show that TV channels allow people to indirectly obtain TV station frequencies. Therefore, in this sense, it is virtual, it may fail because a channel has not been properly tuned, resulting in a snowflake. The indirect advantage is that you only need to compile a piece of code (by Channel 5), and different results may occur each time you execute the Code. (today, Channel 5 is set to five in the center, it can be set to 2 in the center tomorrow, which makes the preceding program (by Channel 5) very flexible. Note that the reason why virtual reality can be flexible is that it must be achieved indirectly through "one means", for example, each channel records a frequency. However, this is not enough. There must be another piece of code that can change the results of that method (the frequency of channel recording), such as redeployment.
First look at virtual inheritance. It indirectly obtains the location of the parent class instance from the subclass instance and implements it through the Virtual class table (this is a "method "), then, you must have "another piece of code" to change the value of the virtual table to show its flexibility. First, you can write this code by yourself, but it requires that you know where the compiler places the virtual class table, and different compilers have different implementation methods, so the compatibility of the written code is very poor. C ++ certainly provides "another piece of code", that is, when a class is falsely inherited multiple times in the same class inheritance system, changes the value of the virtual class table so that the parent class instance indirectly obtained by each subclass is the same. This operation only saves memory. For example:
Struct A {long ;};
Struct B: virtual public A {long B ;}; struct C: virtual public A {long c ;};
Struct D: public B, public C {long d ;};
Here, D has two virtual class tables inherited from B and C respectively. In the constructor of D, the compiler will write the necessary code to correctly initialize the two virtual class tables of D so that the instances of A inherited by B and the virtual class tables inherited by C are the same. one.
Look at the virtual function. Its address is indirectly obtained through the virtual function table (this is a "method"), and then the content of the virtual function table must be changed. Similarly, if you rewrite the code, the code compatibility is poor, and C ++ also provides "another piece of code". Just like above, you can enter the virtual function table in the constructor of the derived class, write the virtual function table based on the current derived class. It must fill a virtual function table with the address of the type, name, and function that is originally defined as a virtual function that matches as much as possible under the current derived class. For example:
Struct A {virtual void ABC (), BCD (float), ABC (float );};
Struct B: public A {virtual void ABC ();};
Struct C: public B {void ABC (float), BCD (float); virtual float CCC (double );};
Struct D: public C {void ABC (), ABC (float), BCD (float );};
In A: A, enter the addresses of two A: ABC and one A: BCD in the virtual function table of.
In B: B, fill B: ABC and the inherited B: BCD and B: ABC in the virtual function table of B.
In C: C, fill C: ABC, C: BCD, And the inherited C: ABC in the virtual function table of C, and add an element: C:: CCC.
In D: D, fill two D: ABC and one D: BCD and the inherited D: CCC in the virtual function table of D.
Here, D inherits from A, B, and C in sequence, and does not generate two virtual function tables because of multiple inheritance. There is only one virtual function table. Although the member functions in D are not modified by virtual, their addresses are still filled in the virtual function table in D, Because virtual only indicates that the member functions need to obtain their addresses indirectly when using them, it has nothing to do with whether to fill in the virtual function table.
Why do TV sets use channels to indirectly obtain the frequency of TV stations? Because the frequency of the TV station is not easy to remember, and if you know a frequency, slowly adjust the capacitance value of the common harmonic capacitor to make the circuit reach that frequency efficiency is very low. For 10 groups of common harmonic circuits, the capacitance values of each group of circuits are adjusted and no longer moved. Different common harmonic circuits are switched to achieve fast conversion frequency. Therefore, the efficiency can be improved indirectly. In addition, Channel 5 is originally a central five, and later it is difficult to replace it with a central two, then the same action (by Channel 5) will produce different results, the program "by Channel 5" is very flexible.
At least we can know from the above: indirectly used to simplify operations, improve efficiency and increase flexibility. The three indirect uses mentioned here are all based on the idea that "one means" is used to achieve the purpose and another piece of code is used to achieve the purpose mentioned above. The virtual inheritance and virtual functions provided by C ++ can be used as long as they are members or virtual functions inherited by virtual inheritance ". To implement "another piece of code", we can see from the above description that it needs to be achieved by means of derivation. You can change the virtual function table by defining the same functions as the virtual function prototype declared in the parent class in the derived class, in the inheritance system of a derived class, the virtual class table can be changed only when the class that has been falsely inherited is repeated, and it only points to the instance of the same class that has been falsely inherited, it is far from convenient and flexible modification of virtual function tables. Therefore, virtual inheritance is not commonly used, while virtual functions are often used.


Virtual use

Because the implementation of "virtual" in C ++ requires the use of derivative means, while derivation is the generation type, the "virtual" is generally mapped to the indirect type, rather than the indirect implementation of the above channel through an instance (a set of common harmonic circuits. Note: The "simplified operation" refers to the complex operation of function ing, which simplifies code writing and indirectly executes the corresponding code using the address mapped by function name, virtual functions are called to present multiple execution results. "Improving Efficiency" is an algorithm improvement, that is, the channel is achieved by repeating ten sets of common harmonic circuits, and the authentic space is changed for time, it is not indirectly implemented on the type. Therefore, the "virtual" in C ++ can only increase code flexibility and simplify operations (for the three indirect advantages proposed above ).
For example, when an animal is called, different animals call different methods and make different sounds. In this case, the type of an animal requires "one means" (called) to show different effects (dogs and cats are called different), and this requires "another piece of code" to implement, that is, through derivation. That is to say, from the Cat and Dog classes of the class Animal, you can declare "Call (Gnar)" as a virtual function in Animal, and then implement the corresponding Gnar member functions in Cat and Dog respectively. As shown in the preceding figure, Animal: Gnar calls have different effects, as shown below:
Cat cat1, cat2; Dog dog; Animal * pA [] ={& cat1, & dog, & cat2 };
For (unsigned long I = 0; I & lt; sizeof (pA); I ++) pA [I]-& gt; Gnar ();
The above container pA records the reference of a series of Animal instances (for reference, refer to "C ++ from scratch (8)"). Its semantics is that this is three animals, as a result, I don't know anything (as if this TV has 10 channels, and I don't know what it is ), each of the three animals is called once (called Animal: Gnar), and the results are followed by the call of a cat, a dog, and a cat. This is what we have said before, increasing flexibility, also known as polymorphism, refers to the same Animal: Gnar call, but shows different forms. The above for loop does not need to be written any more. It is "A means". To change its performance, you can use "another piece of code ", that is, different Derived classes are generated, and the instance reference of the derived classes is placed in the array pA.
Therefore, a member function of a class is declared as a virtual function, indicating the class mapped to this class.ResourcesThe corresponding function should be a usage method, rather than an implementation method. The above "call" indicates that an animal "call" does not have to provide parameters or return values. You can call it directly. Therefore, consider the previous radio and digital radio. If one of the functions is the redeployment function, the corresponding function should be declared as a virtual function to indicate that the frequency increase or decrease will be given for the redeployment, the digital adjustment platform and the ordinary adjustment method are obviously different, but no matter. That is to say, people who use the radio don't care how the station is adjusted, but how the station is redeployed. Therefore, virtual functions indicate that the definition of a function is not important. The declaration of a function is important. A virtual function only has an existing meaning in a derived class. The definition of a virtual function provided by the parent class is redundant. Therefore, C ++ provides a special syntax to allow non-Definition of virtual functions. The format is very simple. Add "= 0" after the declaration statement of the virtual function, it is called a pure virtual function. As follows:
Class Food; class Animal {public: virtual void Gnar () = 0, Eat (Food &) = 0 ;};
Class Cat: public Animal {public: void Gnar (), Eat (Food &);};
Class Dog: public Animal {void Gnar (), Eat (Food &);};
Void Cat: Gnar () {} void Cat: Eat (Food &) {} void Dog: Gnar () {} void Dog: Eat (Food &){}
Void main () {Cat cat; Dog dog; Animal ani ;}
When Animal: Gnar is declared above, "= 0" is written after the statement to indicate that the elements mapped to it are not defined. What is the difference between this and "= 0? You can declare Animal: Gnar directly without defining it. Note that the above Animal ani; will report an error, because in Animal: Animal, the virtual function table of Animal needs to be filled, and it needs the address of Animal: Gnar. If it is a common declaration, no error will be reported here, because the compiler will think that the definition of Animal: Gnar is in another file, and the connector will process it later. However, because "= 0" is used here to inform the compiler that it is not defined, the above Code will fail during compilation, and the compiler has determined that there is no definition of Animal: Gnar.
But what if the Animal: Gnar definition is added above? Animal ani; still reports an error because the compiler has determined that there is no definition of Animal: Gnar, and the generation of the Animal instance is denied even if the function table is not viewed. Therefore, the Animal :: the definition of Gnar is useless. However, the ing element Animal: Gnar now has a number in the address bar, so there is no problem when cat. Animal: Gnar. If the definition of Animal: Gnar is not given, cat. Animal: Gnar (); is still normal, but an error is returned during connection.
Note that the above Dog: Gnar is private, while the Animal: Gnar is public, and the result is dog. gnar (); will report an error while dog. animal: Gnar (); but there is no error (because it is a virtual function result or call Dog: Gnar), that is, the so-called public is irrelevant to the type, it's just a syntax. There is also class Food; you don't have to worry about whether it is declaration or definition. You just need to check what information it provides. There is only one -- there is a type name named "Food", which is a type custom type. When declaring Animal: Eat, the compiler only needs to know that Food is a type name, rather than accidentally typing the wrong word, because Food is not used here.
The above Animal is called a pure virtual base class. The base class is the top class in the class inheritance system; the virtual base class is the base class with pure virtual member functions; the pure virtual base class is a non-pure virtual member function without member variables, only the base class of pure virtual member functions. The above Animal defines a rule, also known as a protocol or an interface. That is, animals can be Gnar and Eat, and an instance of Food must be provided to indicate that animals can Eat Food. That is, the Animal type is a specification, indicating the functionality of an Animal. Its Instance becomes meaningless, and

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.