• Effective C++ Item 34 区分接口继承与实现继承


    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie


    关联条款 Item 36


    接口继承和实现继承不同。在 public 继承下, derived classes 总是继承 base class 的接口

    class Shape{
    public:
    	virtual void draw() const = 0;
    	virtual void error(const std::string &msg);
    	int objectID() const;
    	//...
    };
    
    
    class Rectangle: public Shape{...};
    class Ellipse: public Shape{...};

    1.pure virtual 函数 --> 让 derived classes 仅仅继承函数接口。
    Shape::draw 的声明式仍是对详细 derived classes 设计者说。 “你必须提供一个 draw 函数,但我不干涉你怎么实现它”

    2.impure virtual 函数 --> 让 derived classes 继承该函数的接口和缺省实现
    Shape::error 的声明式告诉 derived classes 设计者说, “你必须支持一个 error 函数,但假设你不想自己写一个,能够使用 Shape要提供的缺省版本号”

    3.non-virtual 函数 --> 让 derived classes 继承函数的接口及一份强制性实现

    class 设计常犯两个错误
    1.将全部函数声明为 non-virtual
    Item 7:为多态基类声明 virtual 析构函数
    2.将全部成员函数声明为 virtual

    经验: impure virtual 函数同一时候指定函数声明和函数缺省行为,可能造成危急。


    演示样例:

    class AirPort{...};
    class AirPlane{
    public:
    	virtual void fly(const AirPort &destination);
    	//...
    };
    void AirPort::fly(const AirPort &destination){
    	//缺省代码。将飞机飞至指定的目的地
    }
    class ModelA: public AirPlane {...};
    class ModelB: public AirPlane {...};
    
    
    class ModelC: public AirPlane {
    	... // 未声明 fly 函数, 但C型飞机的飞行方式与A。B不同。
    };
    
    
    AirPort PDX(...);
    AirPlane *pa = new ModelC;
    //...
    pa->fly(PDX); //调用 AirPlane::fly

    解析:
    这个程序试图以 ModelA, ModelB 的飞行方式来飞 ModelC

    纠正:
    切断“virtual 函数接口” 和 其“缺省实现” 之间的连接。将 AirPlane::fly 改为一个 pure virtual 函数,仅仅提供飞行接口,
    另以独立函数 defaultFly 提供缺省实现。

    class AirPlane{
    public:
    	virtual void fly(const AirPort &destination) = 0;
    	//...
    protected: // protected 由于client不须要在意飞机能不能飞
    	void defaultFly(const AirPort &destination); //Item 36
    };
    
    
    void AirPlane::defaultFly(const AirPlane &destination){
    	//缺省代码,将飞机飞至指定的目的地
    }
    
    
    class ModelA: public AirPlane{
    public:
    	virtual void fly(const AirPort &destination){
    		defaultFly(destination);
    	}
    	//...
    };
    
    
    class ModelB: public AirPlane{
    public:
    	virtual void fly(const AirPort &destination){
    		defaultFly(destination);
    	}
    	//...
    };
    
    
    class ModelC: public AirPlane{
    public:
    	virtual void fly(const AirPort &destination);
    	//...
    };
    
    
    void ModelC::fly(const AirPort &destination){ // pure virtual 函数迫使  ModelC 必须提供自己的 fly 版本号
    	//...
    }

    纠正2:我更喜欢这个,没那么多变量名
    class AirPlane{
    public:
    	virtual void fly(const AirPort &destination) = 0;
    	//...
    protected: // protected 由于client不须要在意飞机能不能飞
    	void defaultFly(const AirPort &destination); //Item 36
    };
    
    
    void AirPlane::fly(const AirPlane &destination){ //pure virtual 函数实现
    	//缺省代码。将飞机飞至指定的目的地
    }
    
    
    class ModelA: public AirPlane{
    public:
    	virtual void fly(const AirPort &destination){
    		AirPlane::fly(destination);
    	}
    	//...
    };
    
    
    class ModelB: public AirPlane{
    public:
    	virtual void fly(const AirPort &destination){
    		AirPlane::fly(destination);
    	}
    	//...
    };
    
    
    class ModelC: public AirPlane{
    public:
    	virtual void fly(const AirPort &destination);
    	//...
    };
    
    
    void ModelC::fly(const AirPort &destination){ // pure virtual 函数迫使  ModelC 必须提供自己的 fly 版本号
    	//...
    }

  • 相关阅读:
    架构师的职责
    open-falcon的插件机制
    gitlab安装
    python把日期转换为秒数;日期转为字符串;datetime、date
    js获取table的值,js获取td里input的值
    grafana结合influxdb、open-falcon出图配置
    centos安装python的虚拟环境和虚拟管理环境
    centos的python2.6.x升级到python2.7.x方法;python2.6.x的版本就不要用了
    openfalcon的安装和使用
    influxdb的python操作
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/6814602.html
Copyright © 2020-2023  润新知