码迷,mamicode.com
首页 > 其他好文 > 详细

绝不重新定义继承而来的缺省参数值

时间:2015-04-24 16:16:13      阅读:117      评论:0      收藏:0      [点我收藏+]

标签:

考虑如下的代码:

class Shape
{
public:
    enum ShapeColor{Red, Green, Blue};
    virtual void draw(ShapeColor color = Red) const = 0;
    ...
};

class Rectangle: public Shape
{
public:
    virtual void draw(ShapeColor color = Green) const;
    ...
};

class Circle: public Shape
{
public:
    virtual void draw(ShapeColor color) const;
    ...
};

以上代码有个问题,如果你用下面的调用方式:

Shape *ps;
Shape *pc = new Circle;
Shape *pr = new Rectangle;

pc->draw(Shape::Red);    //Circle::draw(Shape::Red);
pr
->draw(Shape::Red);    //Rectangle::draw(Shape::Red); pr->draw();          //Rectangle::(Shape::Red)!!!!

我们会发现,pr的动态类型是Rectangle*, 所以调用的是Rectangle的virtual函数,Rectangle::draw的缺省参数应该是GREEN,但是,由于pr的静态类型是Shape*,所以此调用的缺省参数值来自Shape而不是Rectangle。C++之所以这么做,是考虑到运行时效率的问题。如果缺省参数值是动态绑定,编译器就必须在运行期为虚函数决定适当的缺省值。这比目前实行的“在编译器决定”机制更慢更复杂。

那么我们怎么做才适合呢?在派生类里面也提供缺省值吗?

class Shape
{
public:
    enum ShapeColor {Red, Green, Blue};
    virtual void draw(ShapeColor color = Red) const = 0;
    ...
};

class Rectangle: public Shape
{
public:
    virtual void draw(ShapeColor color = Green) const;
    ...
};

Aha,代码重复。

可以用替代设计,比如可以用基类的public 非虚函数调用private的虚函数,后者可以被派生类重新定义,而让非虚函数去做缺省参数的事情。

class Shape
{
public:
    enum ShapeColor { Red, Green, Blue };
    void draw(ShapeColor color = Red) const         //non-virtual
    {
        doDraw(color);
    }
    ...
private:
    virtual void doDraw(ShapeColor color) const = 0;//do the real work
};

class Rectangle : public Shape
{
public:
    ...
private:
    virtual void doDraw(ShapeColor color) const;    //不须指定参数值
    ...
};

绝对不要重新定义一个继承而来的缺省参数值,这些参数值都是静态的,而虚函数却是动态的。

绝不重新定义继承而来的缺省参数值

标签:

原文地址:http://www.cnblogs.com/edmundli/p/4453581.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!