C++:虚函数(virtual function)缺省参数的异常表示及正确利用
制止界说基类(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; }
输出:
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