__jquery of C + + polymorphism and virtual function

Source: Internet
Author: User
Tags function prototype

Polymorphism: Inheritance is a way for subclasses to use the parent class, and polymorphism is the method by which the parent class uses subclasses.

In C + +, there are two kinds of polymorphism, one is function overload, the other is virtual function. The function overload occurs at compile time, and its function arguments are not the same. While a virtual function occurs at run time, its function prototype is the same, depending on the point of the pointer.


There is a very good article about polymorphism and virtual functions. Send a link here.

http://blog.csdn.net/augusdi/article/details/38271009


Such a large pile of nouns, in fact, around one thing, is polymorphic, the other three nouns are for the implementation of C + + polymorphic mechanism of some of the rules proposed, the following two parts introduced, the first part of the introduction of "polymorphism", the second part of "virtual function, pure virtual function, abstract class"

a "polymorphic"

The concept of polymorphism: about polymorphism, several sayings, good and bad, respectively:

1 refers to a variety of forms of the same function.

Personally think this is a high hand of the master like to say, for the general developer is a poor can not be bad concept, is simply misleading people, but people can easily rely on the function overload.

The following are two statements that the individual thinks is better explained:

2 polymorphism is a feature of the ability to perform multiple forms, and in Oo it is the ability of a language to be handled in different ways depending on the type of object, in particular overloaded methods and inherited classes.

This is a bit of a detour, think carefully, this is what C + + to tell us.

3 polymorphism is a technique that allows you to set a parent object to be equal to one or more of his child objects, and after assigning a value, the parent object can operate in a different way depending on the attributes of the child object that is currently assigned to it. To put it simply, it is a sentence that allows a pointer to a subclass type to be assigned to a pointer to a parent class type. Polymorphism is achieved through virtual functions (virtual function) in both Object Pascal and C + +.

This argument seems to be understandable, and comprehensive one, especially the last sentence, directly point out the relationship between the virtual function and polymorphism, if you still do not understand, it does not matter, and then 3 read two times, have an impression, look back.

Two "virtual function, pure virtual function, abstract class"

Polymorphism just said a concept, what use has not been said to enter the second part of the. Look at the last sentence of concept 3, the virtual function is for polymorphic, the introduction of the role of polymorphism and virtual function is simply too big, put together to say it.

Polymorphism : inheritance is a way for subclasses to use the parent class, and polymorphism is the method by which the parent class uses subclasses. This is a vernacular, polymorphism is used to invoke the parent class (specifically the object name of the parent class) to call the subclass's method, for example:

"Example One"

Class A {public

:

A () {}

(virtual) void print () {

cout << ' This is a. ' << Endl

}

} ;

Class B:public A {public

:

B () {}

void print () {

cout << ' This is b. ' << Endl

}

};

int main (int argc, char* argv[]) {

    b b;

A A;  A = B;a.print----------------------------------------make1

//a &a = B; A->print ();--------------------- -------------make2

 //a *a = new B (); A->print ();--------------------------------Make3 return

0;

}

This will show:

This is B.

If you remove the virtual, it will show:

This is A.

(make1,2,3 is the three ways to correspond to the compatibility rules (described later), the result of the call is the same)

Add virtual, polymorphic, and print in B is called, which means that the parent class can be implemented using subclasses.

After a preliminary understanding of the role of polymorphism, a more official and more accurate description of polymorphic effects is presented:

Polymorphism makes it possible to use pointers of the same class (base class) type to refer to objects of different classes, and to perform the same operations in different ways depending on the object being referenced. To look at the different subclass objects as the parent class, we can mask the differences between different subclass objects, write common code, and make general programming to meet the changing requirements. After assignment, the parent object can operate in a different way depending on the attributes of the child object that is currently assigned to it (that is, you can invoke an improved method of the related function of the parent object in the child object).

So why is it that the above example does not call the method in B to remove the virtual? It's obvious that the object of B is assigned to pointer A, because C + + defines a set of compatible rules for assigning objects, meaning that in the case of public derivation, an object of a derived class can be used as a base class object for certain situations. Specifically, the following three scenarios are:

Class A;

Class B:public A

1. Derived objects can be assigned to objects of the base class

A A;

b b;

A = b;

2. A derived object can initialize a reference to a base class

b b;

A &a = b;

3. The address of a derived object can be assigned to a pointer to a base class

b b;

A *a = &b;

Or

A *a = new B ();

It is known from the above object assignment compatibility rule that an object of a base class can be compatible with the object of the derived class. A pointer to a base class can point to an object of a derived class, a reference to a base class can refer to an object of a derived class, and a class of objects cannot be determined at compile time for a call to a member function through an object pointer (or reference) to a base class. It is only at run time to determine and thus determine which class member functions are invoked.

Take a look at just the example, according to the compatibility rule, B's object is simply treated as a object to use, no wonder B's method cannot be invoked.

"Case Two"

#include <iostream>

using namespace std;

Class A

{public

    :

        void (virtual) print () {cout << "A print" <<ENDL;}

        

    Private:

};

Class B:public A

{public

    :

        void print () {cout << "B print" <<ENDL;}

    Private:

};

void Test (A &tmpclass)

{

    tmpclass.print ();

}

int main (void)

{

    b b;

    Test (b);

    GetChar ();

    return 0;
}

This will show:

B Print

If you remove the virtual, it will show:

A Print

So, why add a virtual after the call to achieve the purpose of it, polymorphic AH ~ So why add virtual on the polymorphic, we also want to introduce a concept: the joint

Concatenation of functions: the process of compiling or running a function call with the corresponding function body.

1 advance or static joint: at compile time, the function of the joint is called the advance or static joint.

2 late-delayed or dynamic-linked series: A late or dynamic binder that can be performed at run time.

So what does the link and the virtual function have to do with, of course, the reason for the contradiction in the above example is that the code's binder process uses a forward-linked series, making it impossible for the compile-time system to determine whether to call a function in the base class or to call a function in a derived class, if it is possible to use the late-numbered union mentioned above, You can judge in the end what is the object, so the virtual keyword function is to prompt the compiler to carry out a late link, tell the connection process: "I am a virtual, do not connect me, and so on when the run."

So why the connection when you know exactly which object, this leads to the principle of virtual function: When the compiler encountered virtual, will be the class to construct a table and a pointer, that table is called VTBL, each class has its own VTBL, The function of VTBL is to save the address of the virtual function in the class, we can image the VTBL as an array, each element of the array is the address of the virtual function. The pointer is called VPTR and points to that table. This pointer is stored in the corresponding object, which means that the address of the virtual function cannot be found until the object is created.

Attention

1 to ensure that the base class of the Run-time polymorphic definition is not only the same as the function name of the derived class, the return value and the parameters must be the same, otherwise the system does not carry out the late-linked compilation even if virtual is added.

2 The virtual function relationship is automatically passed to a function of the same name in the base class, in the example above, if the print in a is virtual, then the print in B is automatically considered a virtual function, even if it is not virtual.

*3 has no inheritance relationship, polymorphism mechanism has no meaning, inheritance must be public inheritance.

*4 in reality, this is far more than the two examples I have cited, but the big principle is that "if you find a function that needs to behave differently in a derived class, it should be virtual". This sentence can also be reversed: "If you find that the base class provides a virtual function, then you'd better override it."

pure virtual function:

The function of virtual function is to realize the late Union of the virtual function members in the base class and the derived class, and the pure virtual function is a virtual function member that shows no concrete implementation, that is, the pure virtual function has no implementation code. The effect is simply to introduce a unified framework for its derived classes, which is given in the derived class.

When a function is declared as pure virtual, the pure virtual function means: I am an abstract class. Don't instantiate me. A pure virtual function is used to regulate the behavior of a derived class, which is actually called an "interface". It tells the user that my derived class will have this function.

Abstract class:

A class that contains one or more pure virtual functions is called an abstract class.

"Case Three"

#include <iostream>

 
using namespace std;

Class A
{public
    :

         virtual float print () = 0;

    Protected:

        float h,w;    

    Private:
};

Class B:public A

{public

    :

        B (float h0,float w0) {h = h0;w = W0;}

        float print () {return h*w;}

    Private:

};

Class C:public A

{public

    :

        C (float h0,float w0) {h = h0;w = W0;}

        float print () {return H*W/2;}

    Private:

};

 

int main (void)

{

    A *a1,*a2;

    b b (1,2);

    C c (1,2);

    A1 = &b;

    A2 = &c;

    cout << a1->print () << "," <<a2->print () <<endl;

    GetChar ();

    return 0;
}

The results are:

2,1

In this example, a is an abstract class in which the print in base class A does not determine the specific operation, but cannot be removed from the base class, otherwise the method in the derived class cannot be invoked using a pointer a1,a2 of the base class (A1->print;a2->print is not available). The inconvenience to polymorphism is that we want to invoke a method of a derived class with a pointer to a base class. Want to use the polymorphic mechanism, if the reader does not want to use the base class pointers, think that using the B,c pointer to call the better, the pure virtual function is meaningless, polymorphism is meaningless, understand the benefits of polymorphism, Then decide whether to use pure virtual function bar.

Attention

1 An abstract class cannot directly define an object, it can only declare a pointer as in the previous example, to point to an object of a subclass derived from a base class, a *a1,*a2 in the example above; a a1,a2;

2 A class derived from an abstract class must provide a code implementation for a pure virtual function or still indicate that it is a derived class, otherwise it is wrong.

3 When a class is intended to be used as a base class for other classes, its destructor must be virtual.

"Case Three"

Class A
{public
:
    A () {Ptra_ = new char[10];}
    ~a () {delete[] Ptra_;}        Non-virtual destructor
private:
    char * PTRA_;
};

Class B:public A
{public
:
    B () {ptrb_ = new char[20];}
    ~b () {delete[] ptrb_;}
Private:
    char * ptrb_;
};

void foo ()
{
    A * a = new B;
    Delete A;
}

In this case, the program may not run as you think, and when you execute delete a, only a::~a () is invoked, and the destructor of Class B is not invoked. Whether this is a bit scary. If you change the above A::~a () to virtual, you can ensure that the b::~b () is also called at the time of delete a. Therefore, the destructor of the base class must be virtual. Pure virtual destructor does not have any function, is a virtual enough. It is usually possible to use a pure virtual destructor to achieve an objective only if you want to turn a class into an abstract class (a class that cannot be instantiated), and the class does not have the proper function to be pure-virtual.

Finally, an example is given to illustrate the magical functions of abstract class, pure virtual function and polymorphism:

We want a way to get the different graphic areas and ways:

#include <iostream> using namespace std; Class A//defines an abstract class that is used to compute the area of the graph {public:virtual float areas () = 0;//defines a pure virtual function of the area of calculation, the graph is not determined, when//is not determined by the specific implementation prot    Ected:float h,w;

This assumes that the area of all the graphs can be computed with H and W two elements//to be assumed to be high and long bar private:};

        Class B:public A//defines a category for rectangular area {public:b (float h0,float w0) {h = h0;w = W0;} Float area () {return h*w;}

The concrete realization of pure virtual function of base class private:};

        Class C:public A//defines a public:c (float h0,float w0) for triangle area {h = h0;w = W0;} Float area () {return H*W/2;}

 

The concrete realization of pure virtual function of base class private:};

                            Float Gettotal (a *s[],int N)//pass an array of all graphics objects//polymorphic benefits come out, not polymorphic, cannot be invoked with base class A

       How to write the parameter type, if there are 100 different graphics, how to pass {float sum = 0;

for (int i = 0;i < n; i++) sum = sum + S[i]->area ();

return sum;

int main (void) {float Totalarea;

A *a[2]; A[0] = new B (1,2); A rectangular object a[1] = new C (1,2);//a triangleObject Totalarea = Gettotal (A, 2);//Find out the area of two objects and GetChar ();

return 0; }


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.