代码改变世界

c++ template(8)模版多态

2013-03-29 11:12  Clingingboy  阅读(478)  评论(0编辑  收藏  举报

 

一.传统多态->动多态

image

代码示例:

// common abstract base class GeoObj for geometric objects 
class GeoObj { 
public: 
    // draw geometric object: 
    virtual void draw() const = 0; 
    // return center of gravity of geometric object: 
    virtual Coord center_of_gravity() const = 0; 
    … 
}; 

// concrete geometric object class Circle 
// - derived from GeoObj 
class Circle : public GeoObj { 
public: 
    virtual void draw() const; 
    virtual Coord center_of_gravity() const; 
    … 
}; 

// concrete geometric object class Line 
// - derived from GeoObj 
class Line : public GeoObj { 
public: 
    virtual void draw() const; 
    virtual Coord center_of_gravity() const; 
    … 
}; 

调用示例:

// draw any GeoObj 
void myDraw (GeoObj const& obj) 
{ 
    obj.draw();            // call draw() according to type of object 
} 

// process distance of center of gravity between two GeoObjs 
Coord distance (GeoObj const& x1, GeoObj const& x2) 
{ 
    Coord c = x1.center_of_gravity() - x2.center_of_gravity(); 
    return c.abs();        // return coordinates as absolute values 
} 

// draw inhomogeneous collection of GeoObjs 
void drawElems (std::vector<GeoObj*> const& elems) 
{ 
    for (unsigned i=0; i<elems.size(); ++i) { 
        elems[i]->draw();  // call draw() according to type of element 
    } 
} 
int main() 
{ 
    Line l; 
    Circle c, c1, c2; 

    myDraw(l);            // myDraw(GeoObj&) => Line::draw() 
    myDraw(c);            // myDraw(GeoObj&) => Circle::draw() 

    distance(c1,c2);      // distance(GeoObj&,GeoObj&) 
    distance(l,c);        // distance(GeoObj&,GeoObj&) 

    std::vector<GeoObj*> coll;  // inhomogeneous collection 
    coll.push_back(&l);         // insert line 
    coll.push_back(&c);         // insert circle 
    drawElems(coll);            // draw different kinds of GeoObjs 
} 

二.静多态=>模版

不再需要继承

// draw any GeoObj 
template <typename GeoObj> 
void myDraw (GeoObj const& obj) 
{ 
    obj.draw();    // call draw() according to type of object 
} 

// process distance of center of gravity between two GeoObjs 
template <typename GeoObj1, typename GeoObj2> 
Coord distance (GeoObj1 const& x1, GeoObj2 const& x2) 
{ 
    Coord c = x1.center_of_gravity() - x2.center_of_gravity(); 
    return c.abs();  // return coordinates as absolute values 
} 

// draw homogeneous collection of GeoObjs 
template <typename GeoObj> 
void drawElems (std::vector<GeoObj> const& elems) 
{ 
    for (unsigned i=0; i<elems.size(); ++i) { 
        elems[i].draw();    // call draw() according to type of element 
    } 
} 

int main() 
{ 
    Line l; 
    Circle c, c1, c2; 

    myDraw(l);        // myDraw<Line>(GeoObj&) => Line::draw() 
    myDraw(c);        // myDraw<Circle>(GeoObj&) => Circle::draw() 

    distance(c1,c2);  // distance<Circle,Circle>(GeoObj1&,GeoObj2&) 
    distance(l,c);    // distance<Line,Circle>(GeoObj1&,GeoObj2&) 

    // std::vector<GeoObj*> coll;    // ERROR: no inhomogeneous 
    //        collection possible 
    std::vector<Line> coll;   // OK: homogeneous collection possible 
    coll.push_back(l);        // insert line 
    drawElems(coll);          // draw all lines 
} 

三.比较

动多态:1.需要一个公共基类,2.运行时动态绑定3.生成代码比较小 4.不需要发布源代码

静多态:1.不需要继承关系,2.编译时绑定 3.体积大,执行速度效率高

自有优缺点