When "youyuan" Encounters "virtual functions"

Source: Internet
Author: User

YouyuanIt can be a function called a youyuan function, or a class called a youyuan class.Virtual FunctionsIt must be a non-static member function of the base class. Its access permission can be protected or public.

Basic knowledge:

1. if Class A is A friend of Class B, Class A (member function of Class A) can directly access private members of Class B.

2. youyuan cannot be inherited. That is to say, Class A is the friend of Class B, and Class D is the derived class of Class B, then Class A is not directly the friend of class D. In other words, a father's friend is not a son's friend.

3. No more basic knowledge about virtual functions.

Let's look at the following code:

Code:

 
 
  1. class A;  
  2. class B  
  3. {  
  4. private:  
  5. virtual void output()  
  6. {  
  7. cout << "B::output" << endl;  
  8. }  
  9. friend class A;  
  10. };  
  11. class D : public B  
  12. {  
  13. private:  
  14. virtual void output()  
  15. {  
  16. cout << "D::output" << endl;  
  17. }  
  18. };  
  19.  
 

A is A member of B, and D is A derived class of B. Therefore, if you want to directly access the code of D in A, the compilation will fail:

Code:

 
 
  1. Class
  2. {
  3. Public:
  4. Void test ()
  5. {
  6. D;
  7. D. output (); // compilation Error
  8. }
  9. };

There is no problem with this. After all, the book is clearly and intuitively written: the Friends of the parent class will not become friends of the derived class because of inheritance.

But if the code is changed like this, the compiler seems to be cheated:

Code:

 
 
  1. Class
  2. {
  3. Public:
  4. Void test ()
  5. {
  6. D;
  7. B * pb = & d;
  8. Pb-> output (); // compiled
  9. }
  10. };

Yes, many people think that this kind of code, even through the compiler, is probably a bad kind of code, because it seems to be deceiving the compiler. Is that true? Do not discuss it first. First, let's ask a question: in the above code line 08, is output calling the output of Class B or the one of class D?

Correct answers are not difficult-since this code is determined to be "Spoofed" and noticed that output is a "virtual function"-you can answer the question correctly: class D is called. A is clearly only A friend of B, but through A simple type conversion, It accesses the private function of class D, so it will be considered as A "spoofing ".

If this is a type of deception, let's first answer why the scam was established: Because the resolve was determined during the compilation period, and the virtual function went to resolve during the runtime. When compiling 08 lines of code, the compiler will see that * pb type is B, while A is B's friend, so it is allowed to call output (which is considered B: output ); at runtime, because output is a virtual function, it is finally determined to the D: output header.

I don't have time to look into The Design and Evolution fo C ++ at hand, but whether this Design is intended or helpless, or it's just one of the many "orthogonal" phenomena of C ++. I personally think this feature is exactly what we want.

I. First of all, we need to understand why the derived class should not inherit the "youyuan" of the base class. Many C ++ books have mentioned this.

Ii. Secondly, we need to understand its syntax mechanism: As mentioned above, a compilation phase attribute has met a runtime attribute ......

3. You must understand that if you want to disable this type of spoofing, you cannot. Let's take a look. One of the methods is to check the type of the actually called object during the compilation period. The previous sample code is not difficult to do this, but in the following code, pb comes from a form parameter:

Code:

 
 
  1. A: test_2 (B * pb)
  2. {
  3. Pb-> output (); // it is difficult to identify the actual type of pb during compilation.
  4. // The code that calls test_2 () may be everywhere, or even in the future
  5. }
  6.  

4. Sometimes, people are deliberately doing this. The most typical practice is to call virtual functions through non-virtual functions:

Code:

 
 
  1. Class B
  2. {
  3. Public:
  4. Void Action ()
  5. {
  6. This-> DoAction ();
  7. }
  8. Private:
  9. Virtual void DoAction () = 0; // a private pure virtual function
  10. // Friend class;
  11. };

Any qualified C ++ programmer should learn this practice. DoAction is a pure virtual function. Here we are more decisive. simply make it private, which forces the derived class to implement a completely self-defined DoAction () by itself (), suppose there is a class D: public B, and the DoAction is implemented in an obedient manner. The specific definition of D is not written to save some space.

Note that class A is no longer A member of class B, but it doesn't matter. We just want to call the Action Function in class A of the new version, but it is public, so we don't need friends here.

Code:

 
 
  1. Class
  2. {
  3. Void test ()
  4. {
  5. B * pb = new D; // pb actually points to a D object.
  6. Pb-> Action (); // Action is public, so you can call
  7. }
  8. };
  9.  

Pb calls the non-virtual B: Action function, but calls the virtual function DoAction in the Action. Because pb actually points to the D object, the final call is D :: doAction () -- this is nothing new, right? If you have learned a little C ++ polymorphism, you will understand this. That's right, it's so common. Basically all C ++ programmers write similar code every day-that's what I want to say. Sometimes, it looks like calling the code of the base class, actually, the code of the derived class is called. Assume that we have modified the syntax rules and forced the virtual function to expire after it encounters a friend, that is, it forces the programmer not to use friend to add more private members, use various methods to write them as public.

5. What follows is a concept that seems simple but is misunderstood by many people: Has youyuan destroyed encapsulation? Wrong. youyuan actually promotes better encapsulation. It is based on this requirement: There is a class with several members (data or functions). It can only be made public to other classes. In this case, you can consider using the youyuan technology. If you don't need it, many people will directly change those members to public. As a result, the attribute originally open to individual classes should be changed to open to all classes. It is cheesy that the law stipulates that a wife can look at her husband's fart in private cases. If the law prohibits such exceptions, there may be some friends, if you ask him why, he is innocent: I just want to make my wife more convenient.

6. After reading the fifth point, I had to "test/despise" me for a set of C ++ programmers in OO. Good, well, I know that even the friend attribute is not used, we can also happily implement the aforementioned, similar to my wife's question about her husband's ass-I mean, through OO technology, we can avoid the need to only open permissions to the Department Category, to be converted to a third party (such as an interface and its implementation class)-in any case, you must acknowledge that youyuan has not broken the encapsulation, because others solve this problem, it seems that the more pure OO technology, the better of which lies in the finer class particles and better class organizations (the less beautiful place is that the efficiency is worse, and the idea of OO must be a little level, otherwise it will be dizzy, in order not to let the Cer joke, we do not mention too much ).

7. However, in this case (sixth point), I am still arguing: even in those seemingly pure OO languages, there are actually shadows of youyuan. For example, if Java does not have the friend keyword, its internal class (non-static internal class) can be used to directly access external classes. Isn't it a friend? -- In fact, this is exactly how C ++ uses friend (I don't even need to write "one "). Another example is that Object Pascal (Delphi) does not have the friend keyword, but as long as it is located in the same code unit (that is, the same. pas file), then all the classes are inherently accessible to each other (of course, the first thing to do is to satisfy the visibility)-this is one of the best places I felt when using Delphi, since even more OO languages are reserved, why can't C ++ be used? :)

8. The seventh point is obviously emotional, which does not meet the expectations of the father of C ++: "There is a guiding principle in C ++ design, that is, no matter what you do, all must trust programmers. What is more important than what kind of errors can be made. C ++ programmers are always considered adults ......" . In the vast world of C ++, differences are always respected, and some people do not like to use templates. Some people firmly believe that as long as private and public are enough, forget protected, some people even think that virtual is redundant. Many people use C ++ as another type of C, which is acceptable. The same is true for friend. If you don't need it, its existence will not cause any performance loss to you. What you need to do is to use very OO or not OO, but you are familiar with the method to meet the needs of youyuan.

9. Make sure this is the 9th point. In addition to the youyuan class, the more common is actually the youyuan function. Many operators require a global friend function to reduce the number of public members of the related class. Is "Operator Overloading" useful? Wow, this is another classic problem. It once caused a dispute, which is several times more lively than this "youyuan. Stop.

10. At last, how can beginners of C ++ learn many of these languages and easily produce orthogonal effects? I have a suggestion: first, have a basic understanding and do some exercises, but you don't need to be eager to use them.

Youyuan improves the program running efficiency, that is, it reduces the time overhead required for Type checks and security checks, but it destroys the encapsulation and hiding of classes, this allows non-member functions to invoke private members of the class. Virtual functions are used to achieve polymorphism. Virtual functions and friends always appear in a program at the same time. I hope this article will solve your confusion.

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.