Basic concepts of C ++ (3)-Explanation of polymorphism.

Source: Internet
Author: User

I have to pay attention to polymorphism in the last two interviews. The biggest achievement recently is that basic knowledge is very important. Even if you write code, however, if the interviewer asks you if your basic knowledge cannot be answered, it is difficult to be appreciated and hired. Therefore, you still need to add more basic concepts. This article is about polymorphism.

As mentioned in the first article, polymorphism means that different behaviors occur when the same message is accepted by different objects. There are four categories:Heavy Load polymorphism, forced polymorphism, including PolymorphismAndParameter Polymorphism.

Polymorphism is divided into polymorphism at compile-time. The difference is to determine whether the specific object for the operation is compiled or run.

Heavy Load polymorphism:

We know that the overloading of common functions and member functions of classes belongs to the heavy-load polymorphism.

Function OverloadingBecause it is often used, I believe it is very familiar with it, that is, the number and type of parameters with the same function name are different. When the compiler calls a function, it determines which function to call based on the number of parameter types.

Operator overloadIt is also heavy-load polymorphism. For example, we have defined a Counter class. We hope this class can implement '+' operations, such as Counter a, B, and c; after initialization, there can be c = a + B; or similar operations, so we need to reload '+' and give it an operation rule to ensure that this sentence can be compiled.

(Five operators cannot be overloaded, namely:... *: sizeof? :)

There are two types of Operator Overloading:As a member function overload as a friend function overload.

Syntax format:

As a member function overload OPERATOR: As a friend function overload OPERATOR:

Function Type operator (parameter table ){

............;

}

Operator of the friend function type (parameter table ){

............;

}

 

 

 

 

 

As we have said before, the functions are actually defined outside the functions, so the difference between them and function members is that the functions require two parameters as the values before and after the operators.

For example, I want to reload the +-operation of the Counter Type above:

Counter operator + (Counter c2 ){

Return Counter (this. number + c2.number );

}

// Or you need to overload the minus sign:

Friend Counter operator-(Counter c1, Counter c2 ){

Return Counter (c1.number-c2.number );

}
// Call time:

Counter a (5), B (3), c, d;
C = a + B;
D = a-B;
// All are allowed.

 

//////////////////////////////////////// //////////////////////////////////////// //////////////////////////////////////// /////////////////////////////

In addition to common addition and subtraction operators, there are pre-or post-operators such as -- ++. For example, if we want to define a counter ++, the operators are reloaded as Counter member functions, at the same time, a function must contain an integer (int). The difference is that it is a post ++ --. If it is a prefix, there is no int parameter. As follows:

// Front ++ overload
Counter: operator ++ (){
.........;
}

// Reload of the rear ++

Counter: operator ++ (int ){
...........;
}

// In this way, when the ++ symbol appears, the system can know which function to call based on its location:

Counter A (5 );
A ++; // It is equivalent to Calling operator ++ (0 );
++ A; // It is equivalent to Calling operator ++ ();

Forced polymorphism:

It means that the type of a variable is changed to meet the specific requirements of a function or operation.

For example, when you perform integer and floating-point operations, the integer type is forcibly converted to the floating-point type before the operation.

 

Contains polymorphism:

The inclusion polymorphism is to study the polymorphism behavior of function members with the same name defined in different classes in the class family, mainly implemented through virtual functions.

The virtual function must be a non-static member. After multiple derivation, the family can realize polymorphism during running.

Syntax for virtual function member declaration:

Virtual function type function name (parameter table ){

.......................;

}

The declaration of virtual functions can only be clearly written when the function prototype declaration in the class definition is used, but not when the function body is written. Three rules must be met during running:

1. Classes must meet the type compatibility rules.

2. Declare a virtual function.

3 *.Called by member functions, OrAccess through pointer and referenceVirtual functions.

After understanding the theory, we can understand it by writing a small example.

The complete code is as follows:

Use of virtual functions

# Include <iostream>
Using namespace STD;
Class father {
Public:
Virtual void outputtest (){
Cout <"father" <Endl;
}

};
Class son1: Public father {
Public:
Void outputtest (){
Cout <"son1" <Endl;
}

};
Class son2: Public son1 {
Public:
Void outputtest (){
Cout <"son2" <Endl;
}

};
// Call time
Int main (){
Father F, * P;
Son1 S1;
Son2 S2;
P = & F;
P-> outputtest ();
P = & S1;
P-> outputtest ();
P = & S2;
P-> outputtest ();
}

Let's just say:

We can see that by using the keyword "virtual", we have implemented the inclusion polymorphism of the outputtest function. Among the three classes, outputtest is a virtual function.

Add a sentence: If a function in the subclass is fun and a virtual function fun in the parent class has the same name, parameter table, and return value, the function is automatically determined as a virtual function.

Virtual destructor: It exists to prevent space leakage in some situations. Therefore, virtual constructors are not allowed to exist. At the same time, if the destructor of a parent class is a virtual function, the destructor of the subclass is also a virtual function.

Let's talk about the space leakage: If I defined a parent class Father, which contains no data members, then I defined a subclass Son to inherit the parent class from the public, and there is a private data member * int t; the Son constructor contains t = new int (0);, the Destructor will delete t ;, however, the parent class naturally does not have this sentence. In this case, if we define an object like this: Father * f = new Son (); delete * f; then, Ah ~ It was not surprising that the poor t was so heartless and left in the corner. In this way, if a large program occurs, there may be insufficient memory.

The solution is to add virtual before the Father destructor, in the form of virtual ~ Father (); because it is very simple, I just need to run the code again. It can be done in three minutes:

Virtual destructor code

# Include <iostream>
Using namespace std;
Class Father {
Public:
Father (){};
Virtual ~ Father () {cout <"Father delete;" <endl ;};

};
Class Son: public Father {
Public:
Son () {t = new int (0 );};
~ Son () {delete t; cout <"Son delete;" <endl ;};
Private:
Int * t;

};
// Call time
Int main (){
Father * f = new Son ();
Delete f;
}

Running result:

It can be seen that the destructor of the subclass is called, which avoids the harm caused by memory leakage. So the virtual analysis structure is still very useful ~!

In addition to the above two virtual functions, we should also know the following types:Abstract class.

The abstract class is on the top layer of the class and cannot be instantiated. It can only be instantiated by generating non-Abstract Derived classes from the abstract class through the inheritance mechanism.

Note: classes with pure virtual functions are abstract classes.. But what are pure virtual functions?

A pure virtual function is a virtual function declared in a base class. It has no specific content to operate in this base class, it is used to enable sub-classes to implement different interfaces for this function as needed.

The definition Syntax of pure virtual classes is: virtual function return type function name (parameter table) = 0; in fact, there is a '= 0 '. In this way, you do not need to define the function body. All pure virtual functions do not have the function body.

 

Parameter polymorphism:

Parameter polymorphism refers to parameterization of the types of objects processed by the program, so that a program can be used to process multiple different types of objects.

Parameter polymorphism.Function TemplateOrClass Template.

The so-calledFunction TemplateFor example, we usually use math. many functions in h, such as the absolute value function abs (), can have int, double, and other non-type parameters. If you create an overload function for each type, this is too troublesome. Because the function bodies are the same, we use a template instead, as shown below:

template <typename T>
T abs(T x){
return x<0?-x:x;
}

In this way, if we call the int parameter, the compiler will change T in typename to int. This function returns int, the parameter is an int function, and the double type is the same.

Syntax definition of the function template:

Template <typename T> or template <class T> // indicates that T is a type name or class name, which can be changed to int, double, or a class.

Return type function name (parameter table ){

.........;

} (Note that the return type is not necessarily T ~.)

 

 

 

 

 

 

 

Class template:The class template can be used to declare a mode for the class. In the class, some data members, some member function parameters, and some member functions return values can be of any type.

Syntax definition of a class template: When defining the function body of a member function externally in the class:

Template <template parameter table>

Class name {

...........;

}

Template <template parameter table>

Return type class name <template parameter table member>: function name (parameter table ){

........;

}

 

 

 

 

 

 

Similarly, we use a small example to understand the class template in one second:

# Include <iostream>
Using namespace std;

Template <class Input, class Output>
Class Test {
Public:
Test (Input in) {input = in ;}
Output fun ();

Private:
Input input;
Output output;
};
// Format used to define functions outside the class:
Template <class Input, class Output>
Output Test <Input, Output>: fun (){
Return input> 0? Input:-input;
}



Int main (){
Test <int, int> test (-30 );
Cout <test. fun () <endl;
}

View output:

Success ~! Haha, although there is no gold content, the small program in the format used is used. That's good ~

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.