当前位置:首页 >> 编程开发 >> Visual C++ >> 内容

C++:虚函数(virtual function)缺省参数的异常表现及正确使用

时间:2014/11/16 作者:平凡之路 来源:xuhantao.com 浏览:

避免定义基类(base class)虚函数的缺省参数, 如果基类虚函数包含缺省参数, 派生类不要重新定义, 会产生异常;

虚函数(virtual)是动态绑定(dynamically bound),缺省参数是静态绑定(statically bound).

如果派生类(derived class)重新定义缺省值, 实例化, 执行函数正常;

但在动态绑定时, 会出现,执行基类的缺省参数, 却是派生类的行为, 这样的异常举动.

talk is cheap, show you the code.

注意观察动态绑定时, pr的输出, 表现为基类的缺省参数, 派生类的动作.

代码:

/* 
 * test.cpp 
 * 
 *  Created on: 2014.04.14 
 *      Author: Spike 
 */
      
/*eclipse cdt, gcc 4.8.1*/
      
#include <iostream>  
#include <string>  
      
using namespace std;  
      
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 {  
        std::cout << "Rectangle : ";  
        switch (color) {  
        case Red :  
            std::cout << "color = " << "Red" << std::endl;  
            break;  
        case Green :  
            std::cout << "color = " << "Green" << std::endl;  
            break;  
        case Blue :  
            std::cout << "color = " << "Blue" << std::endl;  
            break;  
        default:  
            break;  
        }  
    }  
};  
      
class Circle : public Shape {  
public:  
    virtual void draw(ShapeColor color) const {  
        std::cout << "Circle : ";  
        switch (color) {  
        case Red :  
            std::cout << "color = " << "Red" << std::endl;  
            break;  
        case Green :  
            std::cout << "color = " << "Green" << std::endl;  
            break;  
        case Blue :  
            std::cout << "color = " << "Blue" << std::endl;  
            break;  
        default:  
            break;  
        }  
    }  
};  
      
int main() {  
    Rectangle R;  
    Circle C;  
    R.draw();  
    //C.draw(); //报错, 静态绑定无法继承参数  
      
    Shape* pr = new Rectangle; //动态绑定  
    Shape* pc = new Circle;  
      
    pr->draw(Shape::Blue);  
    pc->draw(Shape::Blue);  
    pr->draw(); //静态绑定, 使用基类的默认参数, 完成派生类的动作  
    pc->draw();  
      
      
    return 0;  
}

更多精彩内容:http://www.bianceng.cn/Programming/cplus/

输出:

Rectangle : color = Green  
Rectangle : color = Blue  
Circle : color = Blue  
Rectangle : color = Red  
Circle : color = Red

如果想使用基类虚函数的缺省参数, 派生类不提供参数, 则需要使用NVI(non-virtual interface)的方法, 可以直接使用默认参数;

但是, 绝对不要重新定义一个继承而来的缺省参数值.

如, 以下代码中, Rectangle的私有虚函数, doDraw()不要提供默认参数.

代码:

/* 
 * test.cpp 
 * 
 *  Created on: 2014.04.14 
 *      Author: Spike 
 */
      
/*eclipse cdt, gcc 4.8.1*/
      
#include <iostream>  
#include <string>  
      
using namespace std;  
      
class Shape {  
public:  
    enum ShapeColor {Red, Green, Blue};  
    void draw(ShapeColor color = Red) const {  
        doDraw(color);  
    }  
private:  
    virtual void doDraw(ShapeColor color) const = 0;  
};  
      
class Rectangle : public Shape {  
private:  
    virtual void doDraw(ShapeColor color) const {  
        std::cout << "Rectangle : ";  
        switch (color) {  
        case Red :  
            std::cout << "color = " << "Red" << std::endl;  
            break;  
        case Green :  
            std::cout << "color = " << "Green" << std::endl;  
            break;  
        case Blue :  
            std::cout << "color = " << "Blue" << std::endl;  
            break;  
        default:  
            break;  
        }  
    }  

};  
      
int main() {  
    Rectangle R;  
    R.draw();  
      
    Shape* pr = new Rectangle; //动态绑定  
      
    pr->draw(Shape::Blue);  
    pr->draw();  
      
      
    return 0;  
}

输出:

Rectangle : color = Red  
Rectangle : color = Blue  
Rectangle : color = Red

作者:csdn博客 Spike_King

相关文章
  • 没有相关文章
  • 徐汉涛(www.xuhantao.com) © 2024 版权所有 All Rights Reserved.
  • 部分内容来自网络,如有侵权请联系站长尽快处理 站长QQ:965898558(广告及站内业务受理) 网站备案号:蒙ICP备15000590号-1