What is a virtual function? I think if you can express it in words right away, you have a good foundation. Do you know the virtual function table? Maybe you have read a lot of books. In fact, many times you don't need to read a book. Then what is virtual inheritance? I have heard of it, but it is rarely used. In fact, using virtual inheritance can alleviate a lot of your pain.
Let's look at the following example:
The example here is as simple as possible, about virtual functions.
Class father
{
Public:
Father ();
Virtual void run ();
Virtual void say ();
PRIVATE:
Static int I;
};
Int FATHER: I = 2;
Father: Father ()
{
This-> Run ();
}
Void FATHER: Run ()
{
Cout <this-> I <Endl;
This-> say ();
}
Void FATHER: Say ()
{
Cout <"father" <Endl;
}
Class child: Public father
{
Public:
Child ();
Virtual void say ();
PRIVATE:
Static int I;
};
Note: to avoid ambiguity, int I is already of the private type.
Int child: I = 1;
Child: Child (): Father ()
{
};
Void child: Say ()
{
Cout <"child" <Endl;
}
The following test functions:
Int main ()
{
Father X;
Child y;
X. Run ();
Y. Run ();
}
What is the result?
Experienced people may be able to see it at a Glance. I think there should be no problem with both of them. Then, what is the output of the two Constructors?
Some people may say that virtual void run (); is it not virtual? Therefore, when child y calls the constructor, of course the output is 1.
But someone will immediately refute it. Should it be 0 ?, Because child: Child (): Father (), when constructing father (), Child () has not yet been constructed. Of course, the value of Child: I cannot be 1.
In fact, this is not the case. The output is two! Why? Is the virtual function invalid? Actually not. The reason is very simple. You Need To Know That I is not virtual! Why is two father output? There are two arguments: 1. When constructing father, child is not constructed, including the virtual functions that should be inherited. 2: Because father () itself is a function of the father class. Therefore, call the father class method. In fact, these two statements are consistent.
In the next example, you will understand more. This is a complete example:
# Include <iostream>
Using namespace STD;
Class father
{
Public:
Father ();
Virtual void sayj ();
Protected:
Int J;
};
Void FATHER: sayj ()
{
Cout <j <Endl;
}
Class child: Public father
{
Public:
Child ();
Protected:
Int J;
};
Child: Child (): Father ()
{
This-> J = 10;
};
Father: Father ()
{
This-> J = 100;
};
Int main ()
{
Father X;
Child y;
Y. sayj ();
}
What is the result? 100 instead of 10. Here, after the constructor completes the work, it calls sayj. What he calls is actually child-> sayj. Yes, it is inherited from father. However, J is also not virtual. Because sayj is not rewritten in child, it will be found in "parent class! Remember that a virtual function is not a macro and intelligent. It knows that sayj comes from the parent class, so J also comes from the parent class.
Some small errors can be avoided.
Now let's get a question and see if you understand e. It is actually the first example of the question:
# Include <iostream>
Using namespace STD;
Class father
{
Public:
Father ();
Virtual void run ();
Virtual void say ();
PRIVATE:
Static int I;
};
Int FATHER: I = 2;
Father: Father ()
{
This-> Run ();
}
Void FATHER: Run ()
{
Cout <this-> I <Endl;
This-> say ();
}
Void FATHER: Say ()
{
Cout <"father" <Endl;
}
Class child: Public father
{
Public:
Child ();
Virtual void say ();
PRIVATE:
Static int I;
};
Int child: I = 1;
Child: Child (): Father ()
{
};
Void child: Say ()
{
Cout <"child" <Endl;
}
Int main ()
{
Father X;
Child y;
X. Run ();
Y. Run ();
}
What is the result? Static is intended to confuse you.
The result is
2
Father
2
Father
2
Father
2
Child
Right?
Why is the last one "child "? Because say has been rewritten in child! Remember that it is intelligent.
To sum up, the subclass will not be constructed before the parent class is constructed, including the virtual functions that should be inherited!
Even if a virtual function is constructed, the virtual function is not a macro! It is not a simple replacement.
Class variables are not virtual, and constructors are not virtual. (The principle is very simple, but sometimes other interesting theories are also discussed, which makes it more difficult for us to understand the essence)
Let's talk about virtual inheritance. If you understand virtual functions, it is not difficult to inherit virtual functions.
A simple example.
Class cwinbase: Virtual protected igetproc
Class cpaint: Virtual protected igetproc, public cwinbase
If you do not need virtual inheritance, what will happen to the igetproc class? That's ambiguous. Because cwinbase already has an igetproc. (The methods defined above are not good. Do not learn .) This is just to illustrate the problem. The principle of why ambiguous can be removed is actually the same as that of virtual functions. The so-called virtual, that is, when the real operation, there is only one entity. For more information, see professional C ++.
Sometimes give yourself some reminders. No silly mistakes