条款37:绝不重新定义继承而来的缺省参数值
2015-09-20 03:14
579 查看
/*条款37:绝不重新定义继承而来的缺省参数值*/ /*静态绑定就是在程序中被声明时所采用的类型*/ #include<iostream> 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 { //virtual void draw(ShapeColor color = Red)const{ //如果定义与基类相同的缺省参数,会产生相依性问题,如果基类缺省值改变,子类也必须改变 cout << "Rectangle::draw" << endl; } //这里赋予不同缺省参数值 too bad!! }; class Circle :public Shape { public: virtual void draw(ShapeColor color)const { cout << "Circle::draw" << endl; } //如果调用此函数时,一定要指定参数,因为静态绑定这个函数并不从其基类中继承缺省参数值,但以指针或引用调用,可以不指定参数值,因为动态绑定下这个函数会从其基类继承缺省参数值 };*/ // 第24行问题的解决方法 NVI手法 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 { public: //.. private: virtual void doDraw(ShapeColor color)const {}//这里无须指定缺省参数值,而且缺省参数总为Red ,更改基类缺省无需更改子类缺省 }; class Circle :public Shape { public: virtual void doDraw(ShapeColor color)const { cout << "Circle::draw" << endl; } //如果调用此函数时,一定要指定参数,因为静态绑定这个函数并不从其基类中继承缺省参数值,但以指针或引用调用,可以不指定参数值,因为动态绑定下这个函数会从其基类继承缺省参数值 }; int main() { /* Shape*ps; //静态类型为Shape* 无动态类型 因未有指向 Shape*pc = new Circle; //静态类型为Shape* 动态类型为Circle* Shape*pr = new Rectangle;//静态类型为Shape* 动态类型为Rectangle* // ps,pc,pr都被声明为P t s类型,无论它们指向什么,它们的静态类型都是Shape* //动态类型指“目前所指对象的类型”,也就是说动态类型可以表现出一个对象将会有什么行为 //动态类型可以在程序执行过程中改变(通常是由赋值动作) ps = pc; //ps 如今的动态类型是Circle* ps = pr;//ps 如今的动态类型是Rectangle* //所以虚函数系动态绑定而来,意思是调用一个虚函数时,究竟调用哪一份函数实现代码,取决于发出调用的那个对象的动态类型 pc->draw(Shape::Red); //调用Circle::draw(Shape::Red) pr->draw(Shape::Red);//调用Rectangle::draw(Shape::Red) //花样来了 virtual函数是动态绑定,但缺省参数值却是静态绑定 pr->draw();//Rectangle::draw.... Shape 与Rec的声明各出一半力 //这种乖张的方式动作是因为效率问题,如果缺省参数是动态绑定,编译器须有某种办法在运行期为虚函数决定适当的参数缺省值,比编译期决定更慢更复杂, */ //----------------------- system("pause"); return 0; }
相关文章推荐
- 分析Hibernate的事务处理机制
- 为什么hibernate需要事务?
- Unique Paths II 解答
- Socket原理
- Java对象的驻留
- java中的线程通信
- Android笔记(三十四) Android中线程之间的通信(六)Handle中的post()方法详解
- 升级xcode7 和 iOS9 后遇到的问题以及解决方案
- JAV线程取消方式
- Java线程池
- centos6.5单机编译配置mysql主从
- html_基础之form表单提交、label 、for、table
- Unique Paths 解答
- iOS开发 关于SEL的简单总结
- Jenkins自动构建VS的代码20150607
- 软工实践l练习一一利用github托管项目
- 成绩查询程序
- Maximum Subarray 解答
- 简单配置nginx
- Something about Binary search tree