base class
Class Shape {public
:
shape () {
cout << "construct shape" << Endl;
}
~shape () {
cout << "Deconstruct Shape" << Endl;
}
Virtual Double Calarea () {
cout << "Shape calarea" << Endl;
return 0;
}
;
Sub Class
Class Circle:public Shape {public
:
Circle () {
cout << "construct Circle" << Endl;
}
~circle () {
cout << "Deconstruct Circle" << Endl;
}
The virtual here is not necessary, if not added, the system will automatically add,
//For the readability of the code, recommended add
virtual double Calarea () {
cout << "Circle Calarea "<< Endl;
return 0;
}
;
class object vs class Pointer
object of the class: Circle Circle;
a pointer to a class: circle* p_circle = new Circle ();
The class object passes the "." Call Function:
Circle.calarea ();
The class pointer invokes the function through "->":
P_circle->calarea ();
The object of the class is the stack memory, which is a partial temporary variable.
A pointer to a class: Use heap memory, which is a permanent variable unless you release it.
Why does the object of the class also have the use of a pointer to the class? The pointer can implement polymorphism , the object of the class cannot be called in the function call, as far as possible to pass the reference or pointer parameters. No matter how large your object or structural parameters are, use a pointer to pass through an address that is 4 bytes. If you use an object, parameter passing is too large for the resource.
What is polymorphism?
The same object receives different messages or different actions from different objects when they receive the same message.
The function of the object invocation of the class is its own member function:
main1
int Main () {
Circle C;
C.calarea ();
cout << Endl;
Shape s;
S.calarea ();
cout << enld;
}
******* Execution Results ***********
Construct Shape
Construct Circle
Circle Calarea
Construct Shape
Shape Calarea
Deconstruct shape//Destructor Shape object s
Deconstruct Circle
Deconstruct Shape
Note that the above results show that calling the constructor of the parent class (in contrast to the destructor of the subclass and then calling the parent class) is the function of its own member function before the child function is constructed:
Note that the Calarea () function in the base class shape is a virtual function (virtual) and, if not declared as a virtual function, executes the result of the following code:
main2
int Main () {
Circle C;
C.calarea ();
cout << Endl;
shape* p = new Circle ();
P->calarea ();
Delete p; Call Delete to destructor, otherwise cout << Endl will not be refactored
;
******* Execution Results ***********
Construct Shape
Construct Circle
Circle Calarea
Construct Shape
Construct Circle
Shape calarea //pointer p calls a function of the parent class
Deconstruct Shape// "1" delete p, the pointer p only invokes the destructor of the parent class, no destructor subclass, memory leak
Deconstruct Circle
Deconstruct Shape
After the Calarea function in the shape of the parent class is declared virtual, then the MAIN2 code is executed, with the following results:
******* Execution Results ***********
Construct Shape
Construct Circle
Circle Calarea
Construct Shape
Construct Circle
Circle calarea //pointer p calls a subclass of a function
Deconstruct Shape
Deconstruct Circle
Deconstruct Shape
To avoid the memory leak problem described in "1", the destructor of the parent class is declared as a virtual function:
~virtual shape () {
cout << "deconstruct shape" << Endl;
}
This is what object the parent pointer is pointing to, and which object's constructor executes first, and then executes the constructor of the parent class. The destructor of a subclass is also executed when it is destroyed.
Why virtual can achieve polymorphism
static binding: compile-time binding, called by object. Before the program executes, the compiler has resolved which function to call.
Dynamic binding: Run-time binding, implemented by Address (virtual function table). When the program is running, it resolves which function to call.
Virtual functions can be dynamically bound, and to trigger dynamic binding, two conditions must be met: only virtual functions can be dynamically bound, and non-virtual functions are not dynamically bound. A function call must be made through a reference or pointer to a base class type.
The use of virtual in a function limit ordinary functions can not be virtual functions, that is, this function must be a member of a class function, can not be a global function, or cause a compilation error. A static member function cannot be a virtual function. Static member functions coexist with a similar life, he does not belong to any object, and using virtual will also cause errors. An inline function cannot be a virtual function if an inline function is modified by virtual, the computer ignores the inline to make it a virtual function of the existence. Constructors cannot be virtual functions, otherwise a compilation error occurs.
the principle of multi-state realization
Virtual function table pointer: In addition to the defined function member in the class, there is also a member that is a virtual function table pointer (accounting for four basic internal certificates), this pointer points to the starting position of a virtual function table that appears with the definition of the class, which holds the virtual function pointer of the class, and the virtual function table pointer of the class can be found when invoked. The virtual function table is found by the virtual function table pointer, and the entry address of the function is found by the offset of the virtual function table, which finds the virtual function to be used.
When instantiating a subclass object of the class, the (if) the subclass of the class does not define a virtual function, but inherits the virtual function from the parent class, a virtual function table is also generated when the class subclass object is instantiated, and the virtual function table is a virtual function table of subclasses. However, the virtual function addresses of the recorded subclasses are the same as those of the parent class. Therefore, the virtual function table of the subclass object finds its own virtual function table, and the function pointer that is found in its own virtual function table is also the address of the corresponding function entry of the parent class.
If we define a virtual function that inherits from the parent class in the subclass, the situation is constant for the parent class, and the virtual function table for the subclass is the same as the previous virtual function table, but at this point the subclass defines its own corresponding function (inherited from the parent class). So the pointer to the function in its virtual function will overwrite the value of the original pointer to the parent class function. In other words, you point to the corresponding function that you defined, so that if you point to the object of the subclass with the pointer of the parent class, you find the virtual function table of the subclass from the virtual function table pointer in the subclass object, Thus, the virtual function table of subclasses is found, and the address of the virtual function defined by the function itself is not the corresponding virtual function entry address of the parent class, so the virtual function in the subclass will be executed. This is the principle of polymorphism.
overlay and hide of functions
A function with the same name as the parent class and subclass appears hidden. Parent class object. function function name (...); Invokes a function subclass object of the parent class. Function name (...); The function subclass object that invokes the subclass. Parent class Name:: Function name (...); A subclass invokes a function inherited from the parent class.
A virtual function with the same name and a parent class and subclass is called overriding
-The parent class pointer =new the subclass name (...); \quad the parent class pointer-> function name (...); /Invoke a virtual function of a subclass
Pure virtual function
pure virtual function definition:
\quad pure virtual functions do not have function bodies and, at the time of definition, add "= 0" after the function name.
Class Shape
{public
:
virtual Double CalcArea ()//virtual function
{}
virtual double Calcperimeter () =0;//pure virtual function
};
Classes that contain pure virtual functions become abstract classes Abstract classes cannot be instantiated, and subclasses that inherit the abstract class can also be abstract classes, and abstract class subclasses can instantiate objects only if all pure virtual functions in the abstract class are implemented.
If the abstract class contains only pure virtual functions and nothing else, we call them interface class . There are no data members only member function member functions are pure virtual functions