C + + template--dynamic polymorphism and static polymorphism (vi)

Source: Internet
Author: User

Several previous posts have introduced the basics of the template, and have also explained in depth the features of the template. In the next blog post, you'll get an introduction to the template and design.
------------------------------------------------------------------------------------------------------------
Compared to traditional language constructs, the template differs in that it allows us to parameterize types and functions in code. Combining (1) local and (2) recursive instantiation will produce powerful power. In the next few posts, we demonstrate these power through some of the following design techniques:
(1) Generic programming
(2) Trait
(3) Policy class
(4) metaprogramming
(5) Expression template

------------------------------------------------------------------------------------------------------------
14th. polymorphic Power of templates
Polymorphism is the ability to associate a single generic tag with different specific behaviors. For object-oriented programming paradigm, polymorphism can be said to be a cornerstone. In C + +, this cornerstone is implemented primarily through inheritance and virtual functions. Since both mechanisms (inheritance and virtual functions) are processed at runtime (at least a portion), we call this polymorphic polymorphic, which is what we normally talk about in C + + polymorphism. However, the template also allows us to use a single generic tag to correlate different specific behaviors, but this (template-based) association is processed at compile time, so we refer to this (template-based) polymorphism as static polymorphism, which distinguishes it from the dynamic polymorphism above.
------------------------------------------------------------------------------------------------------------
14.1 Dynamic Polymorphism

Using inheritance and virtual functions, in this case, the multi-state design idea mainly lies in: for the types of several related objects, determine a common feature set between them; then in the base class, these common functions are declared as multiple virtual function interfaces. Each concrete class derives from the base class, and after the concrete object is generated, the client code can manipulate the objects by pointing to a reference or pointer to the base class, and can implement the virtual function scheduling mechanism through these references or pointers. That is, invoking a virtual member function with a pointer or reference to a base class (sub-object) will actually invoke the corresponding member of the concrete class object (which the pointer or reference actually represents). This dynamic polymorphism is the most common in C + + programming, here is not too much elaboration.

14.2 static polymorphic templates can also be used to achieve polymorphism. Here's an example:

//poly/statichier.hpp#include"coord.hpp"//specific Geometric object class Circle//-and not derived from any other classclasscircle{ Public:        voidDraw ()Const; Coord center_of_gravity ()Const; ...};//specific Geometric object class line//-and not derived from any other classclassline{ Public:        voidDraw ()Const; Coord center_of_gravity ()Const; ...}; ....

The applications that use these classes now look like the following:

//Poly/staticpoly.cpp#include"statichier.hpp"#include<vector>//Draw any geoobj//method2Template <typename geoobj>voidMydraw (geoobjConst& obj)//geoobj is a template parameter{Obj.draw (); //call the corresponding draw () based on the type of object}......intMain () {line L;    Circle C;         Mydraw (l); //mydraw<line> (geoobj&) = line::d Raw ()Mydraw (c);//mydraw<circle> (geoobj&) = Circle::d Raw ()}//method1: If you use dynamic polymorphism, the Mydraw function will be the following form:voidMydraw (geoobjConst& obj)//Geoobj is an abstract base class{Obj.draw ();}

By comparing these two implementations of Mydraw (), we can see that the main difference is that the specification of METHOD2 geoobj is a template parameter, not a common base class. There are, however, more fundamental differences behind this phenomenon. For example, with dynamic polymorphism (METHOD1), we only have one mydraw () function at run time, and if we use a template, we may have several different functions, such as mydraw<line> () and mydraw<circle> ().

14.3 dynamic polymorphic and static polymorphism

We will classify the polymorphism and compare the two polymorphic states.

14.3.1 terminology

Dynamic polymorphism and static polymorphism provide support for different C + + programming Idioms:
(1) The polymorphism implemented by inheritance is bound and dynamic:
1. The implication of the binding is that for types that participate in polymorphic behavior, the interfaces (with polymorphic behavior) are predetermined in the design of the public base class (and sometimes the concept of binding is called intrusion or insertion).
2. Polymorphism means that the binding of an interface is done at run time (dynamic).
(2) Multiple states implemented through templates are non-binding and static:
1. The implication of non-binding is that for types that participate in polymorphic behavior, their interfaces are not predetermined (sometimes referred to as non-invasive or non-intrusive).
2. The static meaning is: The binding of the interface is completed at compile time (static).

14.3.2 Advantages and Disadvantages
(1) The dynamic polymorphism of C + + has the following advantages:
1. Able to gracefully handle heterogeneous collections;
2. The size of executable code is usually small (because only one polymorphic function is required, but for static polymorphism, in order to handle different types, several different template instances must be generated);
3. The code can be fully compiled, so there is no need to publish the implementation source (however, the distribution template Library usually need to publish the template implementation of the source code);
(2) On the other hand, C + + static polymorphism has the following advantages:

1. You can easily implement a collection of built-in types. More broadly, there is no need to express the commonality of interfaces through public base classes;

2. The generated code is generally more efficient (because there is no indirect call through pointers, and there are more inline opportunities for non-virtual functions that can be deductive);

3. For a specific type that only provides a partial interface, if you are using only this part of the interface in your application, you can use that specific type without having to care whether the type provides an interface for the other part.

In general, static polymorphism is considered to have better type safety than dynamic polymorphism: Because static polymorphism checks all binding operations at compile time. For example, suppose we try to insert an object of the wrong type into a container, and if the container is produced from a template instantiation, it is almost no danger because the error can be checked at compile time, but if the element that the container expects is a pointer to a common base class, Then these pointers will likely end up pointing to different types of complete objects, which could insert an object of the wrong type.

In real-world applications, the template instantiation (static polymorphism) can sometimes cause problems if there are some semantic assumptions hidden behind them for seemingly identical interfaces. For example, for a template that assumes that there is an associated operator +, if you instantiate the template based on a type that does not have the operator associated with it, then there are some problems. However, this semantic mismatch is seldom seen in polymorphic systems based on inheritance because the common interface specification has been explicitly specified in the base class.

14.3.3 combination of these two polymorphic

Obviously, you can combine these two forms of polymorphism. For example, you can derive different kinds of geometric object classes from a common base class to handle different geometries that belong to heterogeneous collections. On the other hand, you can still use templates to write code for some kind of geometry object.

The combination of inheritance and templates will be further elaborated in the later post xxxx. In the 16th chapter, we will see how to parameterize the virtual nature of member functions, and what additional flexibility the static polymorphism sacrifices when using a singular recursive template pattern based on inheritance.

14.4 New forms of design templates

This new form of static polymorphism brings a new way to implement design patterns. For example, take a bridge pattern that plays an important role in C + + programming. The purpose of using bridge mode is to be able to switch between multiple instances of the same interface. We can usually use a pointer to refer to the specific implementation, and then delegate all the calls to this (with the implementation-specific) class to achieve our goal (see Figure 14.3)

However, if the type of implementation is already deterministic at compile time, then we can use the template method to implement the bridge mode (see Figure 14.4). This will lead to better type safety and also avoids the use of pointers, and can also lead to higher efficiency.

14.5 Generic Programming
So far, the most notable contribution in the field of C + + generic programming is the STL (Standard Template Library), which was later adopted and introduced into the C + + standards Library. The STL uses iterators to parameterize operations, thus avoiding the excessive expansion of operation definitions. In this case, you do not need to implement each operation for each container, you can apply the algorithm to each container only once. In other words, the "binder" of generic programming is the iterator provided by the container and can be used by the algorithm. The reason an iterator can shoulder this task is because the container provides some specific interfaces for the iterator, and the algorithm uses these interfaces. We often refer to each of these interfaces as a concept (i.e., constraints), which shows that a template (that is, a container) must fulfill or implement these constraints (i.e., conforming to the STL framework standard) If it is to be incorporated into this framework (i.e., STL).
In principle, it is also possible to use dynamic polymorphism to implement these STL-like functions. However, the use of dynamic polymorphic implementations is bound to be very limited, because the virtual function call mechanism of dynamic polymorphism will be a heavyweight implementation mechanism compared with the concept of iterators, which will have a great effect on efficiency. Adding a layer of interfaces based on virtual functions, for example, usually affects the efficiency of operations, and the degree of this impact can be several orders of magnitude (or even more severe).
In fact, generic programming is quite practical, because it relies on static polymorphism, and static polymorphism requires parsing the interface at compile time. On the other hand, this requirement (that is, parsing the interface at compile time) also brings some new design principles that are quite different from object-oriented programming principles.

C + + template--dynamic polymorphism and static polymorphism (vi)

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.