zoukankan      html  css  js  c++  java
  • 条款37:绝不重新定义继承而来的缺省参数值

    1、绝不重新定义继承而来的缺省参数值所牵涉的范围?

    继承的函数分为两种:non-virtualvirtual。而non-virtual函数是完全不能重新定义的(函数体、缺省参数都不可以),因此我们所说的绝不重新定义继承而来的缺省参数值实际指的是virtual函数。

    2、为什么不能重新定义继承而来的缺省参数值?

    因为virtual 函数体是动态绑定的,但是virtual 函数的缺省参数是静态绑定的。假如通过指针或者引用访问重新定义继承而来的virtual函数的缺省参数值,则会造成错误。(例如:函数体为派生类版本,但是缺省参数却是基类版本。)

    注意:C++编译器将 virtual函数体设为动态的,而将virtual的缺省参数设为静态的是出于效率的考虑。如果缺省参数设为动态的,程序运行机制会变得更慢、更复杂。

    3、何谓静态绑定和动态绑定?

    • 静态绑定,又叫前期绑定。
      对象的静态类型,就是它在程序中被声明时所采用的类型。

    • 动态绑定又叫后期绑定。

    • 对象的动态类型指的是指针(或引用)目前所指对象的类型。动态类型可以表现出一个对象将会有什么行为。动态类型可以在执行过程中被改变。

    举例:

    在这里插入图片描述

    //ps、pc、pr 的静态类型为 Shape*
         Shape* ps;						//ps 动态类型:无
         Shape* pc = new Circle;		//pc动态类型:圆形
         Shape* pr = new Rectangle;		//pr动态类型: 矩形
    	
    	 ps = pc;						
    	 ps = pr;						//动态类型可以在运行期间改变。
    

    4、在遵守该规则的前提下,如何做到同时给base classderived class 提供缺省参数?

    方案一:一般手法,基类和所有派生类提供一模一样的缺省参数。
    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 = Red) const;
        ...
    };
    
    

    代码的缺点:

    • 重复度大。(每个派生类都要指定缺省参数ShapeColor color等于Red )
    • 灵活性差。(当基类的缺省参数改变时,所有派生类的缺省参数也要跟着修改。)
    方案二:NVI手法替代方案
    class Shape {
    public:
        enum ShapeColor {Red, Green, Blue};
        void draw(ShapeColor color = Red) const            //如今它是non-virtual
        {
            doDraw(color);                                 //调用一个virtual
        }
        ...
    private:
        virtual void doDraw(ShapeColor color) const = 0;    //真正的工作在此处完成
    };
    
    class Rectangle: public Shape{
    public:
        ...
    private:
        virtual void doDraw(ShapeColor color) const;        //注意,无须指定缺省参数值。
        ...
    };
    
    
    Shape * rec = new Rectangle();
    rec->draw();			//  缺省参数调用,缺省参数为Red  矩形版本draw()
    rec->draw(Green);		//  带参数调用					 矩形版本draw()
    

    优点:

    • 基类缺省发生改变,派生类不需要修改参数。
  • 相关阅读:
    华为FusionCloud云计算vCPU资源计算公式(MHz)
    Jenkins入门总结
    前端构建工具gulp使用 (转)
    大窍决:放松,放松,再放松! 高僧开示汇编
    万物在这种绝对真性中自然解脱! 顶果钦哲仁波切
    阿姜查:为何我们生于此?|这个世界的真相
    与「法」同住世间
    阿姜查:哪里有迷妄,哪里便有平静
    阿姜查:不必让自己成为什么 一切顺其自然就好
    阿姜查:当心碰到外尘时,才是真正修行的开始
  • 原文地址:https://www.cnblogs.com/lasnitch/p/12764187.html
Copyright © 2011-2022 走看看