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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • MySQL多表查询核心优化

    MySQL多表查询核心优化在一般的项目开发中,对数据表的多表查询是必不可少的。而对于存在大量数据量的情况时(例如百万级数据量),我们就需要从数据库的各个方面来进行优化,本文就先从多表查询开始。

    2022年6月2日
    39
  • 文件夹打不开如何修复_为知笔记使用教程

    文件夹打不开如何修复_为知笔记使用教程呃….虽然是展示了笔记,但最为苦恼的一个问题,黏贴代码时,它竟然连序号都会粘上….最近再看谷粒学苑的笔记时,发现是ziw后缀的笔记,于是在网上下载了。呃~~下载好了打开文件一看,还是一如既往的会黏贴代码序号~,下载之后发现根本打不开文件,于是再次问度娘~~~通过发送的方式,将笔记发送到为知笔记软件里去。通过这个大神网友的评论才突然发现,原来是。的版本bug,下载旧版本就OK了。然后又再次找解决方法~~~的选项,找到以下目录,并把。…

    2022年10月12日
    6
  • phpstorm2021永久激活码[在线序列号][通俗易懂]

    phpstorm2021永久激活码[在线序列号],https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月19日
    71
  • 双重求和∑matlab_求和∑的性质

    双重求和∑matlab_求和∑的性质目录一、复习求和符号∑二、二重求和的定义三、双重求和∑∑交换求和顺序一、复习求和符号∑    自从约瑟夫·傅立叶于1820年引入求和符号∑(大写的希腊字母sigma)以来,求和∑以及双重求和∑∑在数学公式推导,命题证明中被经常使用,掌握它的定义和性质对于提高我们的数学能力是必不可少的。注意我们在此只讨论有限项的求和。结合律:∑i=1n(ai+b…

    2022年10月12日
    3
  • 单模光纤的传输距离比多模光纤的传输距离_单模多模单模光纤传感器

    单模光纤的传输距离比多模光纤的传输距离_单模多模单模光纤传感器1.1000Base-SX及1000Base-LX是什么意思?短波长光传输1000Base-SX、长波长光传输1000Base-LX多模光纤可以分为长波激光(称为1000BaseLX)和短波激光(称为1000BaseSX)。2.千兆位以太网标准问题:请问多模和单模光纤的极限传输距离是多少?标准光纤类型光纤直径(μm)最大传输距离1000base-sx多模62.5260m1000base-sx…

    2022年8月30日
    4
  • java的学生信息管理系统_学生管理系统java

    java的学生信息管理系统_学生管理系统java导读正文本文实例为大家分享了java学生信息管理系统的具体代码,实现学生信息:增加int[]a=newint[9]、删除、查找、更改,供大家参考,具体内容如下/*学生信息管理系统,实现学生信息:*增加int[]a=newint[9]*删除*查找*更改*/importjava.util.Scanner;//导入java输入流importjava.lang.*;importja…

    2025年12月4日
    4

发表回复

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

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