C ++ polymorphism dynamic and static polymorphism

Transfer from http://www.cnblogs.com/lizhenghn/p/3667681.html
today's C ++ is already a multiple generic programming language (multiparadigm programming lauguage), while supporting a process in the form of (procedural), object-oriented form (object-oriented ), functional form (Functional), generic form (generic), meta programmatically (as metaprogramming) language. These capabilities make the C ++ and flexibility unmatched become a tool, but may also lead to some confusing users, such as polymorphism. In these types of generic programming, object-oriented programming, and generic programming is a new form of meta-programming support the concept of polymorphism, but different. C ++ supports multiple forms of multi-state, from form performance point of view, there are virtual functions, templates, and other heavy-duty, from the binding time point of view, can be divided into static and dynamic multi-state multi-state, also called compile time polymorphism and run-time polymorphism.

This article is about the similarities and differences between them. Note that generic programming and meta-programming is usually implemented in the form of a template, so in this article describes object-oriented dynamic programming based on the template and polymorphic static polymorphic forms. In fact, in addition macros can also be considered as a way to implement static polymorphism, the principle is to achieve full replacement, but the C ++ language itself is not like macros, which also ignored the "macro polymorphism."

What is the dynamic multi-state?
Dynamic polymorphism design: related object type for determining a common feature set between them, then the base class, these common features declared as a plurality of virtual common function interface. Subclasses override these respective virtual function, to perform specific functions. Client code (operation function) to manipulate these objects by reference or pointer pointing to the base class virtual function call will be automatically bound to the subclass object actually provided up.

It can be seen from the above definition, thanks to the virtual function, so polymorphism is done dynamically at runtime, also called run-time polymorphism, which created a powerful dynamic polymorphism mechanism when processing heterogeneous collection of objects power (of course, with a little bit performance loss).

namespace DynamicPoly
{
    class Geometry
    {
    public:
        virtual void Draw()const = 0;
    };

    class Line : public Geometry
    {
    public:
        virtual void Draw()const{    std::cout << "Line Draw()\n";    }
    };

    class Circle : public Geometry
    {
    public:
        virtual void Draw()const{    std::cout << "Circle Draw()\n";    }
    };

    class Rectangle : public Geometry
    {
    public:
        virtual void Draw()const{    std::cout << "Rectangle Draw()\n";    }
    };

    void DrawGeometry(const Geometry *geo)
    {
        geo->Draw();
    }

    //动态多态最吸引人之处在于处理异质对象集合的能力
    void DrawGeometry(std::vector<DynamicPoly::Geometry*> vecGeo)
    {
        const size_t size = vecGeo.size();
        for(size_t i = 0; i < size; ++i)
            vecGeo[i]->Draw();
    }
}

void test_dynamic_polymorphism()
{
    DynamicPoly::Line line;
    DynamicPoly::Circle circle;
    DynamicPoly::Rectangle rect;
    DynamicPoly::DrawGeometry(&circle);

    std::vector<DynamicPoly::Geometry*> vec;
    vec.push_back(&line);
    vec.push_back(&circle);
    vec.push_back(&rect);
    DynamicPoly::DrawGeometry(vec);
}

Polymorphism is the dynamic nature of the design of object-oriented inheritance, the concept of polymorphism. Dynamic interfaces are polymorphic in explicit interface (virtual function), for example,

For the above codes, it requires:

1. Since w is declared as type Widget, it must support the Widget w interfaces, and these interfaces can often find (such Widget.h) in the source, these interfaces is a display interface;
2.Widget may just be a group class, he has sub-categories, that is to say Widget interface may be the virtual functions (such as the above normalize), this time the call to the interface on the performance of the run-time polymorphism;

What is a static polymorphism?
Static polymorphism design ideas: For related object type, directly implement their respective definitions, it does not require a total base class, even without any relationship. Need only implement each specific class declarations require the same interface, where the interface is called implicit interface. The client operation function definition template for these objects, when the object what type of operation required, which directly specifies the type of argument to the template (or obtained by argument deduction).

With respect to the object-oriented programming, interfaces explicitly and run-time polymorphism (virtual function) dynamic polymorphism, the template programming and generic programming, and is implicit interface compiler to implement static polymorphism polymorphism.

namespace StaticPoly
{
    class Line
    {
    public:
        void Draw()const{    std::cout << "Line Draw()\n";    }
    };

    class Circle
    {
    public:
        void Draw(const char* name=NULL)const{    std::cout << "Circle Draw()\n";    }
    };

    class Rectangle
    {
    public:
        void Draw(int i = 0)const{    std::cout << "Rectangle Draw()\n";    }
    };

    template<typename Geometry>
    void DrawGeometry(const Geometry& geo)
    {
        geo.Draw();
    }

    template<typename Geometry>
    void DrawGeometry(std::vector<Geometry> vecGeo)
    {
        const size_t size = vecGeo.size();
        for(size_t i = 0; i < size; ++i)
            vecGeo[i].Draw();
    }
}

void test_static_polymorphism()
{
    StaticPoly::Line line;
    StaticPoly::Circle circle;
    StaticPoly::Rectangle rect;
    StaticPoly::DrawGeometry(circle);

    std::vector<StaticPoly::Line> vecLines;
    StaticPoly::Line line2;
    StaticPoly::Line line3;
    vecLines.push_back(line);
    vecLines.push_back(line2);
    vecLines.push_back(line3);
    //vecLines.push_back(&circle); //编译错误,已不再能够处理异质对象
    //vecLines.push_back(&rect);    //编译错误,已不再能够处理异质对象
    StaticPoly::DrawGeometry(vecLines);

    std::vector<StaticPoly::Circle> vecCircles;
    vecCircles.push_back(circle);
    StaticPoly::DrawGeometry(circle);
}

Static polymorphism essentially with the template of now. Static interface call is called polymorphism is also implicit interface, a display interface with respect to the formula by a signature function (i.e. the function name, parameter types, the return type) constituted by the active interface is usually an implicit expression composed, for example,

template<typename Widget,typename Other>
void DoSomething(Widget& w, const Other& someNasty)
{
    if( w.size() > 0 && w != someNasty) //someNastyT可能是是T类型的某一实例,也可能不是
    {
        Widget temp(w);
        temp.normalize();
        temp.swap(w);
    }
}

It seems requirements:

1. Type T need to support size, normalize, swap function, copy constructor, you can compare ranging
2. Type T is the only instantiated show different function calls at compile the template, this time calling for the interface polymorphic when it showed compile.
but,

1.size function does not need to return an integer value to 10 and Comparative even need to return a numeric type, the only constraint is that it returns an object of type X, and X of type int and the object (10 Type Value ) can be called a operator>, the operator> X does not necessarily have a type of argument can not, it can be converted to an object of type Y by implicit conversion can type X, Y and only need to type and can compare to an int (good convoluted, see, this side also confirmed the programming template compilation error is difficult to solve).
2. The same type T does not need to support operator! =, But only X can be converted to an object of type T, someNastyT can be converted to an object of type Y, and X and Y may be unequal to compare.
Dynamic and static polymorphic polymorphic comparative
static polymorphism
advantages:

1. Since the static polymorphism is completed at compile time, a higher efficiency can be optimized compiler;
2. strong fit and loose coupling, such as by partial specialization, to full specialization handle special types;
3. the most important thing is to bring through a static polymorphic C ++ template programming is the concept of generic design, such as the powerful STL library.
Disadvantages:

1. Because it is a template to implement static polymorphism, and therefore inadequate template that is static polymorphism disadvantages, such as debugging difficult, time-consuming to compile, code bloat, supported by the compiler compatibility
2. Not able to handle heterogeneous collections of objects
dynamically polymorphic
advantages:

1.OO design, intuitive understanding of the objective world;
2. To achieve separation of the interface, reusable
3. Under the same processing power of heterogeneous collection of objects of inheritance system
Disadvantages:

1. Run-bound, resulting in some degree of overhead to run;
2. the compiler can not optimize the virtual function
3. heavy class inheritance system, changes to the interface affects the entire class hierarchy;
different points:
1. different nature, static polymorphism determined at compile, now complete with the template, determined dynamically at runtime polymorphism by inheritance, virtual functions implemented;
2. dynamic polymorphism is explicit in the interface to the signature function as the center, polymorphic in operation of the virtual functions implemented by, multi-station interface is a static implicit expression for the effective center, polymorphic template having now complete compilation of
similarities:
1 are able to achieve polymorphism, the polymorphic static / compiled multi-state, multi-state dynamic / run polymorphism;
2 that the connector can be achieved and phase separation, a template is defined in the interface, define the type of parameters to achieve, a base class virtual function is defined in the interface, the class is responsible for implementing inheritance;

Attach all the code for this test.

namespace DynamicPoly
{
    class Geometry
    {
    public:
        virtual void Draw()const = 0;
    };

    class Line : public Geometry
    {
    public:
        virtual void Draw()const{    std::cout << "Line Draw()\n";    }
    };

    class Circle : public Geometry
    {
    public:
        virtual void Draw()const{    std::cout << "Circle Draw()\n";    }
    };

    class Rectangle : public Geometry
    {
    public:
        virtual void Draw()const{    std::cout << "Rectangle Draw()\n";    }
    };

    void DrawGeometry(const Geometry *geo)
    {
        geo->Draw();
    }

    //动态多态最吸引人之处在于处理异质对象集合的能力
    void DrawGeometry(std::vector<DynamicPoly::Geometry*> vecGeo)
    {
        const size_t size = vecGeo.size();
        for(size_t i = 0; i < size; ++i)
            vecGeo[i]->Draw();
    }
}

namespace StaticPoly
{
    class Line
    {
    public:
        void Draw()const{    std::cout << "Line Draw()\n";    }
    };

    class Circle
    {
    public:
        void Draw(const char* name=NULL)const{    std::cout << "Circle Draw()\n";    }
    };

    class Rectangle
    {
    public:
        void Draw(int i = 0)const{    std::cout << "Rectangle Draw()\n";    }
    };

    template<typename Geometry>
    void DrawGeometry(const Geometry& geo)
    {
        geo.Draw();
    }

    template<typename Geometry>
    void DrawGeometry(std::vector<Geometry> vecGeo)
    {
        const size_t size = vecGeo.size();
        for(size_t i = 0; i < size; ++i)
            vecGeo[i].Draw();
    }
}

void test_dynamic_polymorphism()
{
    DynamicPoly::Line line;
    DynamicPoly::Circle circle;
    DynamicPoly::Rectangle rect;
    DynamicPoly::DrawGeometry(&circle);

    std::vector<DynamicPoly::Geometry*> vec;
    vec.push_back(&line);
    vec.push_back(&circle);
    vec.push_back(&rect);
    DynamicPoly::DrawGeometry(vec);
}

void test_static_polymorphism()
{
    StaticPoly::Line line;
    StaticPoly::Circle circle;
    StaticPoly::Rectangle rect;
    StaticPoly::DrawGeometry(circle);

    std::vector<StaticPoly::Line> vecLines;
    StaticPoly::Line line2;
    StaticPoly::Line line3;
    vecLines.push_back(line);
    vecLines.push_back(line2);
    vecLines.push_back(line3);
    //vecLines.push_back(&circle); //编译错误,已不再能够处理异质对象
    //vecLines.push_back(&rect);    //编译错误,已不再能够处理异质对象
    StaticPoly::DrawGeometry(vecLines);

    std::vector<StaticPoly::Circle> vecCircles;
    vecCircles.push_back(circle);
    StaticPoly::DrawGeometry(circle);
}

/**无法编译通过,因此Widget要求有显式接口,但现在看不到*/
//void DoSomething(Widget& w)
//{
//    if( w.size() > 0 && w != someNastyWidget)
//    {
//        Widget temp(w);
//        temp.normalize();
//        temp.swap(w);
//    }
//}

/**可以编译通过,因此此处只是要求了只有在模板具现时需保证下面可编译(无调用,无具现)*/
template<typename Widget,typename Other>
void DoSomething(Widget& w, const Other& someNasty)
{
    if( w.size() > 0 && w != someNasty) //someNastyT可能是是T类型的某一实例,也可能不是
    {
        Widget temp(w);
        temp.normalize();
        temp.swap(w);
    }
}

Static_Dynamic_Polymorphism.cpp
Published 46 original articles · won praise 13 · views 60000 +

Guess you like

Origin blog.csdn.net/luliuliu1234/article/details/80156155