Http://blog.163.com/localvar@126/blog/static/1053355200691974613755/
# Include < Iostream. h >
Class Fairytale
{
Public :
Virtual Void Act1 () {cout < " Princess meets Frog " < Endl; Act2 ();}
Void Act2 () {cout < " Princess kisses frog " < Endl; act3 ();}
Virtual Void Act3 () {cout < " Frog turns into Prince " < Endl; act4 ();}
Virtual Void Act4 () {cout < " They live happily ever after " < Endl; act5 ();}
Void Act5 () {cout < " The end " < Endl ;}
};
Class Unhappytale: Public Fairytale
{
Public :
Void Act3 () {cout < " Frog stays a frog " < Endl; act4 ();} // Overriden
Void Act4 () {cout < " Princess runs away in disgust " < Endl; act5 ();} // Overiden
Void Ac5 () {cout < " The not-so-happy end " < Endl ;} // Hide
};
Void Main ()
{
Char C;
Fairytale * Tale;
Cout < " Which tale wocould you like to hear (F/U )? " ;
CIN > C;
If (C = ' F ' )
{
Tale = New Fairytale; // Dynamically allocate and assign the fairytale-like address to tale;
}
Else
{
Tale = New Unhappytale;
}
Tale -> Act1 ();
Delete tale;
}
Result Analysis
Input F
Princess meets Frog
Princess kisses frog
Frog turns into Prince
They live happily ever after
The end
When u is input, the result is
Princess meets Frog
Princess kisses frog // the above two sentences are determined by the inheritance relationship. Although unhappytale does not have void act1 () or void Act2 (), both of them are inherited from fairytale and act1 () is a virtual function
Frog stay a frog // dynamically concatenate tale = new unhappytale; point to the virtual function act3 () in unhappytale (although there is no keyword "virtual" before, it is determined by the inheritance relationship)
Princess runs away in disgust
The end // when act5 () is called, it is determined by fairytale * tale because it is a static Association.
*/
/*
In a member function of a base class or derived class, you can directly call a virtual function in the class level. For example:
Class A
{
Public :
Virtual Void Act1 () {Act2 ();}
Void Act2 () {act3 ();}
Virtual Void Act3 () {act4 ();}
Virtual Void Act4 () {act5 ();}
Void Act5 () {cout < " The end " < Endl ;}
};
Class B: Public A
{
Public :
Void Act3 () {act4 ();}
Void Act4 () {act5 ();}
Void Act5 () {cout < " All done " < Endl;
}
Since non-virtual function calls adopt static concatenationProgramYou don't have to run it.
Call Statement in the function act1 () in the base class:
Act2 (); The Act2 () function in its class is called, that is, a: Act2 (). Similarly, the base class member function act4 () calls a: act5 ()
The member function act4 () in the derived class B calls B: act5 ()
*/
/*
Specific problems must be analyzed for virtual functions. For example:
B;
B. act1 ();
In this case, the call sequence of each member function is as follows:
A: act1 ()-> A: Act2 ()-> B: act3 ()-> B: act4 ()-> B: act5 ()
In this case, we can use the this pointer for analysis. For example, a: Act2 () can be rewritten:
Void A: Act2 ()
{
This-> act3 ();
}
In the preceding example, this points to B, so a: Act2 () calls B: act3 ().
A;
A. act1 ();
You can use Dag to analyze the calling process of the virtual function in the above example, draw the Dag consisting of the most derived class B and its base class, and list only
The virtual function name. We use Class B as an example.
A {act1 (), act3 (), act4 ()} A {act1 ()}
B inherited from a deletes the dominant name in the base class, as shown in the right figure.
B {act3 (), act4 ()} B {act3 (), act4 ()}
The DAG in the right figure determines the execution process of the virtual function when the actual object is B. That is, if
When act3 () or act4 () is called, the virtual function defined in B is always called. If act1 () is called, the virtual function in a is always called.
*/
/*
You can use the member name restriction to prevent member functions of the base class from calling virtual functions in the derived class. For example:
Void A: act3 () {A: act4 ();}
Void B: act3 () {A: act4 ();}
In this case, the call to act4 () uses static concatenation, that is, the call to act4 () in ()
*/