标签:
在继承中,分为两类函数:virtual和non-virtual。而重新定义一个非虚函数是不好的(条款36),那么以下的讨论就是如何定义继承而来的虚函数。
强调:虚函数是动态绑定的,而缺省参数值是静态绑定的。
1 #include <iostream> 2 3 class Shape 4 { 5 public: 6 enum ShapeColor{ Red, Green, Blue }; 7 virtual void draw(ShapeColor color = Red) const = 0; 8 }; 9 10 class Rectangle : public Shape 11 { 12 public: 13 virtual void draw(ShapeColor color = Green) const; // 混淆设计:重新定义了继承而来的缺省参数值 14 }; 15 void Rectangle::draw(ShapeColor color) const 16 { 17 std::cout << color << std::endl; 18 } 19 20 class Circle : public Shape 21 { 22 public: 23 virtual void draw(ShapeColor color) const; // 24 }; 25 void Circle::draw(ShapeColor color) const 26 { 27 std::cout << color << std::endl; 28 } 29 30 int main() 31 { 32 Shape* ps; // 静态类型为Shape* 33 Shape* pr = new Rectangle; // 静态类型为Shape* 34 Shape* pc = new Circle; // 静态类型为Shape* 35 36 pr->draw(); // 相当于调用了Rectangle::draw(Shape::Red) 37 pr->draw(Rectangle::Green); // 调用Rectangle::draw(Rectangle::Green) 38 pc->draw(Circle::Blue); // 调用Circle::draw(Circle::Blue) 39 40 return 0; 41 } 42
说明:
关于类型:ps、pr、pc不论其指向什么,静态类型都为Shape*。所谓动态类型,就是当前所指对象的类型,如,pr的动态类型是Rectangle*,pc的动态类型是Circle*,ps未指向任何对象,因此没有动态类型。
关于重定义缺省值:如上例中的pr->draw(),我们的本意可能是调用Rectangle::draw(Rectangle::Green),可实际上调用的是Rectangle::draw(Shape::Red),结果就是:调用的是派生类的函数,而使用的却是基类的默认参数,真是不伦不类。导致这种结果的原因就是:缺省参数值是静态绑定的,其总是根据pr的静态类型去寻找默认参数值,我们必须避免这种糟糕的设计。
标签:
原文地址:http://www.cnblogs.com/benxintuzi/p/4525620.html