Effective C++ — 继承和面向对象设计

Effective C++ — 继承和面向对象设计

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

32.确保你的public继承了模is-a关系

public继承意味着is-a关系(里氏替换原则),一切适用于基类也适用于派生类。
矩形继承正方形问题:

  • 可实施与矩形的操作无法实施与正方形
  • 在编程领域。正方形是一种矩形是错误的
  • 在现实领域,正方形是一种矩形是正确的

33.避免遮盖继承而来的名称

class Base {
private:
    int x;
public:
    virtual void mf1() = 0;
    virtual void mf1(int);
    virtual void mf2();
    void mf3();
    void mf3(double);
};
class Derived:public Base {
public:
    virtual void mf1();
    void mf3();
    void mf4();
};

Derived d;
int x;
d.mf1();    // 调用Derived::mf1
d.mf1(x);   // 错误,由于Derived::mf1遮掩了Base::mf1
d.mf2();    // 调用Base::mf2
d.mf3();    // 调用Derived::mf3
d.mf3(x);   // 错误,由于Derived::mf3遮掩了Base::mf3

继承类函数会遮掩基类的同名函数。即使參数不同。
目的是防止继承类从基类继承重载函数。

解决方法例如以下:

class Derived:public Base {
public:
    using Base::mf1;// 让Base class内mf1的全部东西在继承类作用域中都可见
    using Base::mf3;
    virtual void mf1();
    void mf3();
    void mf4();
};

为了让遮掩重见天日。可使用using声明式或者转交函数。

34.区分接口继承和实现继承

  1. 接口继承
  2. 接口和实现继承,同一时候覆写
  3. 接口和实现继承。不覆写
class Shape {
public:
    virtual void draw() const = 0;// 接口继承
    virtual void error(const string& msg);// 接口和实现继承。同一时候覆写
    int object() const;// 接口和实现继承,不覆写 
};

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

类A提供纯虚函数及实现fly()。期望继承类B使用fly实现,继承类C不使用fly实现。C类的实现者可能不清楚这一约定,造成类C也使用fly的实现。

解决方法:
1. 将fly改为纯虚函数。类A中实现protected defaultfly。

类B实现fly中调用defaultfly。类C实现fly。
2. 将fly改为纯虚函数,类A中提供fly的定义,类B实现的fly中调用A::fly(),类C实现fly

结论:

  • 声明为纯虚函数期望继承类仅仅继承接口。
  • 声明为虚函数目的是让继承类继承该函数的接口和缺省默认实现
  • 声明为非虚函数目的是让继承类继承函数的接口和一份强制的实现

35.考虑virtual函数以外的其它选择

  • NVI Non-Virtual Interface用来替代public virtual的方案
  • 由Function Pointers实现strategy模式
  • 古典策略模式
    遗留问题:
    tr1::function使用

36.绝不又一次定义继承而来的non-virtual函数

non-virtual代表不变性凌驾与特异性。

目的是令继承类继承函数的接口及一份强制实现
使用基类指针会调用到基类的版本号

37.绝不重定义继承而来的缺省參数

非虚函数中不同意在继承类中重定义
在虚函数中更改继承类的缺省參数不会起作用
虚函数中更改缺省參数不起作用的原因,出于效率考虑,在运行期确定參数比编译器决定慢且更为复杂
虚函数中不要提供缺省參数,虚函数改动缺省參数后,继承类要跟着改动
使用NVI(non-virtual infterace方法。non-virtual方法中提供缺省參数,no-virtaul方法调用virtual方法)

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 Rectangel:public Shape {
private:
    virtual void doDraw(ShapeColor color) const;
};

38.通过复合塑模出has-a或“依据某物实现出”

复合的两层含义

  • has-a(应用域对象,比如汽车,视频画面)
  • is-implemented-in-terms-of(实现域,比如缓存器。相互排斥器)

39.明智而审慎地使用private继承

  • 假设是private继承,须要基类对象的场合。传入继承类错误,编译器不会自己主动将继承类对象转换为一个基类对象。
  • 由private继承而来的全部成员,在继承类中都会变为private
  • private继承意味着implemented-in-terms-of(依据某物实现)
  • 继承类和基类没有不论什么关系
  • private继承意味着实现被继承,接口部分被略去。private继承在设计层面没有意义
  • 和复合之间的取舍
    • 尽可能使用复合
    • 须要改动private继承基类中的虚函数时使用私有继承
    • 替代私有继承须要更改虚函数的还有一种方法: 使用复合,复合类中定义一个public继承的嵌套类,复合类使用该嵌套了的对象。
class Widget {
private:
    class WidgetTimer:public Timer {
    publicvirtual void OnTick() const;
    };
    WidgetTimer timer;
}; 

以上方式也能够用来阻止继承类又一次定义virtual函数

  • 使用private的还有一个场合:EBO empty base optimization空白基类最优化(STL中使用 unary_function,binary_function)

版权声明:本文博客原创文章,博客,未经同意,不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117461.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 搜索优化_百度搜索关键词

    搜索优化_百度搜索关键词一个网站其实很简单,但难的是在于那些搜索引擎如(google,yahoo,msn等)如何找到你,并提高排名!最近,我总结了7条最新、最重要的注意事项1.网站优化是为了访问者,而不是针对搜索引擎。  这一点是做网站的终极目标,请牢记这一点。搜索引擎优化要考虑用户体验,用户体验这个东西最重要的了,我们做站就是为了客户所以用户体验是非常重要是第一位的。其次在用户体验的基础之上很好地进行搜

    2025年7月29日
    4
  • unity开发微信小游戏1[通俗易懂]

    unity开发微信小游戏1[通俗易懂]unity开发微信小游戏

    2025年5月31日
    2
  • 2022pycharm 激活码(JetBrains全家桶)

    (2022pycharm 激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~40ZKSWCX8G-eyJsaWNlb…

    2022年4月2日
    199
  • Web前端和Web后端的区分「建议收藏」

    一、绪论1、前台:呈现给用户的视觉和基本的操作。后台:用户浏览网页时,我们看不见的后台数据跑动。后台包括前端、后端。前端:对应我们写的html、css、javascript等网页语言作用在前端网页。后端:对应jsp、javaBean、dao层、action层和service层的业务逻辑代码。(包括数据库)为什么jsp是后端呢?主要是jsp的运行原理是在tomcat服务器运…

    2022年4月18日
    47
  • mysql之视图、索引

    mysql之视图、索引视图 什么是视图 视图(View)是一种虚拟存在的表,同真实表一样,视图也由列和行构成,但视图并不实际存在于数据库中。行和列的数据来自于定义视图的查询中所使用的表,并且还是在使用视图时动态生成的。数据库中只存放了视图的定义,并没有存放视图中的数据,这些数据都存放在定义视图查询所引用的真实表中。使用视图查询数据时,数据库会从真实表中取出对应的数据。因此,视图中的数据是依赖于真实表中的数据的。一旦真实表中的数据发生改变,显示在视图中的数据也会发生改变。 视图的作用 定制用户数据,聚焦

    2022年7月22日
    12
  • SSM整合(狂神版)

    SSM整合(狂神版)SSM整合数据库环境环境依赖pom.xml建立基本结构mybatis-config.xmlapplicationContext.xml数据库环境CREATEDATABASE`ssmbuild`;USE`ssmbuild`;DROPTABLEIFEXISTS`books`;CREATETABLE`books`(`bookID`INT(10)NOTNULLAUTO_INCREMENTCOMMENT’书id’,`bookName`VARCHAR(100)NO

    2022年5月7日
    47

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号