【Effection C++】读书笔记 条款34~条款35

来源:互联网 发布:淘宝卖家店铺出租 编辑:程序博客网 时间:2024/05/16 08:49

【Effection C++】继承与面向对象设计

条款34 区分接口继承和实现继承

1. 声明一个pure virtual函数的目的是为了让derived class只继承函数接口

这是有一点需要注意,对于一个函数pure virtual函数的抽象基类是无法实例化的,无论是通过new,还是直接声明对象,编译器都会报错。

但是,对于一个纯虚函数,我们是可以给这个纯虚函数提供相应的函数定义的,并且也可以执行成功,可以通过作用域来指定需要执行的函数。

2. 声明impure virtual函数的目的,是为了让derived class 继承该函数的接口和缺省实现

这种情况下,基类一般提供一种缺省实现,派生类根据自己的实际需求来判断是否需要覆盖基类的缺省实现。

除此之外,如果担心新的派生类因为遗忘了设计独立的实现,而错误的使用了缺省实现,可以参考pure function可以有着相应的定义,但是在调用时候必须明确指明。这种特性帮助我们设计派生类的时候,如果需要缺省实现就明确要求,否则就自己设计。

3. 声明non-virtual的目的是为了让derived class继承函数的接口及一份强制实现

用non-virtual函数的意义在于,其不变性凌驾于特异性之上。

相关代码示例

class Shape{public:    virtual void draw() = 0;                       // 只提供接口    virtual void error(const std::string& msg);    // 提供接口的同时提供一份默认的实现,派生类可以修改为自己的实现版本    int objectID() const;                          // 提供接口的同时提供一份强制性的实现,派生类一般不应该修改该实现};void Shape::draw(){    cout << "Shape::draw()" << endl;}void Shape::error(const std::string& msg)   // 接口的默认实现{    cout << msg << endl;}int Shape::objectID() const                 // 接口的强制实现{    return 0;}class Rectangle : public Shape{    virtual void draw();};void Rectangle::draw(){    cout << "Rectangle::draw()" << endl;}int main(){    int id;    Shape* ps1 = new Rectangle;    ps1->draw();                            // 调用Rectangle::draw    ps1->error("Shape::error");             // 调用Shape::error    id = ps1->objectID();                   // 调用Shape::objectID    ps1->Shape::draw();                     // 调用Shape::draw()    return 0;}

条款35:考虑virtual函数之外的选择

藉由Non-Virtual Interface 手法实现Template Methon模式

这里主要是由设计一个non-virtual函数来设定接口或者执行的框架,但是函数内则调用相应的虚函数来完成具体的实现,这样子,算法的框架整体上相同,但是实现却又不相同。

class GameCharacter{public:    int healthValue() const    {        ……  //做事前工作        int retVal=doHealthValue();//真正做实际工作        ……  //做事后工作        return retVal;    }    ……private:    virtual int doHealthValue() const //derived classes可以重新定义    {        ……    }};

藉由Function Pointer实现Strategy模式

将virtual function 替换为“函数指针成员变量”,这是Strategy设计模式的一种分解表现形式

其他Strategy模式

使用function成员变量替换virtual函数,因而允许任何可调用物搭配一个兼容于需求的签名式。

或者将继承体系中的virtual函数替换为另一个继承体系内的virtual函数。传统的Strategy设计模式的实现手法。

阅读全文
0 0