第14章 C++中的代码重用

1. 使用公有继承时,类可以继承接口,可能还有实现(基类的纯虚函数提供接口,但不提供实现)。获得接口是is-a关系的组成部分。而使用组合,类可以获得实现,但不能获得接口。不继承接口是has-a关系的组成部分。

2. C++还有另一种实现has-a关系的途径——私有继承。使用私有继承,基类的公有成员和保护成员都将称为派生类的私有成员。这意味着基类方法将不会称为派生类对象公有接口的一部分,但可以在派生类的成员函数中使用它们。

3. 包含将对象作为一个命名的成员对象添加到类中,而私有继承将对象作为一个未命名的继承对象添加到类中。我们将使用术语子对象(subobject)来表示通过继承或包含添加的对象。

因此,私有继承提供的特性和包含相同:获得实现,但不获得接口。所以,私有继承也可以用来实现has-a关系。

4. 要进行私有继承,请使用关键字private来定义类。实际上,private是默认值,因此省略访问限定符也将导致私有继承。

5. 使用包含还是继承来建立has-a关系

大多数C++程序员倾向于包含。首先,它易于理解。类声明中包含表示被包含类的显示命名对象,代码可以通过名称引用这些对象,而使用继承将使关系更抽象。其次,继承会引起很多问题,尤其从多个基类继承时,可能必须处理很多问题,如包含同名方法的独立的基类或共享祖先的独立基类。总之,使用包含不太可能遇到这样的麻烦。另外,包含能够包括多个同类的子对象。如果某个类需要3个string对象,可以使用包含声明3个独立的string成员。而继承只能使用一个这样的对象(当对象都没有名称时,将难以区分)。

6. 通常,应使用包含来建立has-a关系;如果新类需要访问原有类的保护成员,或需要重新定义虚函数,则应使用私有继承。

7. 使用保护继承时,基类的公有成员和保护成员都将称为派生类的保护成员。和私有继承一样,基类的接口在派生类中也是可用的,但在继承层次结构之外是不可用的。当从派生类派生出另一个类时,私有继承和保护继承的主要区别便呈现出来了。使用私有继承时,第三代类将不能使用基类的接口,是因为基类的公有方法在派生类中将变成私有方法;使用保护继承时,基类的公有方法和保护方法在第二代类中将变成保护的,因此第三代类可以使用它们。保护继承和私有继承一样,都是表示has-a关系。

8. 隐式向上转换意味着无需进行显式类型转换,就可以将基类指针或引用指向派生类对象。

公有继承能隐式向上转换,保护继承只能在派生类中才能隐式类型转换,私有继承不能隐式类型转换。

9. 使用using重新定义访问权限

使用保护派生或私有派生时,基类的公有成员将称为保护成员或私有成员。假如要让基类的方法在派生类外面可用,方法之一是定义一个使用该基类方法的派生类方法。另一种方法是使用using声明,来指出派生类可以使用的特定基类成员,即使采用的是私有派生(注意:using声明只使用函数名,没有圆括号、函数特征标和返回类型)。P550

10. 多重继承MI可能会给程序员带来很多问题。其中两个主要的问题是:从两个不同的基类继承同名方法;从两个或更多相关基类那里继承同一个类的多个实例。

11. 虚基类使得从多个类(它们的基类相同)派生出的对象只继承一个基类对象。例如:通过在类声明中使用virtual,可以使Worker被用作Singer和Waiter的虚基类(virtual和public的次序无关紧要):

class Singer : virtual public Worker{…}

class Waiter : public virtual Worker{…}

然后,可以将SingingWaiter类定义为:

class SingingWaiter : public Singer, public Waiter{…}

12. P557-P558虚基类新的构造函数规则

C++在基类是虚的时,为避免信息传递冲突,禁止信息通过中间类自动传递给基类。然而,编译器必须在构造派生对象之前构造基类对象组件。如果没有显示指出构造函数,编译器将调用虚基类的默认构造函数。如果不希望通过默认构造函数来构造虚基类对象,则需要显式地调用所需的基类构造函数。

13. P558哪个方法

多重继承可能导致函数调用的二义性。可以使用作用域解析运算符来澄清编程者的意图。

SingingWaiter newhire(“Elise Hawks”, 2005, 6, soprano);

newhire.Singer::Show();

然而,更好的方法是在SingingWaiter中重新定义Show(),并指出要使用哪个Show()。

14. 混合使用虚基类和非虚基类

当类通过多条虚途径和非虚途径继承某个特定的基类时,该类将包含一个表示所有的虚途径的基类子对象和分别表示各条非虚途径的多个基类子对象。

15. 模板类以template <class Type>(或template <typename Type>)打头,如果在类声明外定义类方法,每个函数头还需加上模板前缀template <class Type>和类限定符(Stack<Type>::)。

16. 知道模板类不是类和成员函数定义至关重要。它们是C++编译器指令,说明了如何生成类和成员函数定义。不能将模板成员函数放在独立的实现文件中。由于模板不是函数,它们不能单独编译。为此,最简单的方法是将所有模板信息放在一个单独的头文件中,并在要使用这些模板的文件中包含该头文件。

17. P574-P575,在类声明中,都可以使用Stack;在类外,在模板函数定义内(包括形参)可以使用Stack,指定返回类型或使用作用域解析运算符时,必须使用完整的Stack<Type>。

18. template <class T, int n>中,T为类型参数,n为非类型参数或表达式参数。表达式参数有一些限制。表达式参数可以是整形、枚举、引用或指针。因此,double m是不合法的,double *rm和double *pm是合法的。另外,模版代码不能修改参数的值,也不能使用参数的地址。即不能使用n++或&n等表达式。另外,实例化模板时,用作表达式参数的值必须为常量表达式。

19. P578-P582模板多功能性(将模板类用作基类、组件类、或其他模板的类型参数)、递归使用模板、使用多个类型参数。

20. 模板的具体化

类模板和函数模板很相似,因为可以有隐式实例化、显式实例化和显式具体化,它们统称为具体化。

1)  隐式实例化:

ArrayTP<int, 100> stuff;

编译器在需要对象之前,不会生成类的隐式实例化:

ArrayTP<int, 100> *pt;//不需要对象

pt = new ArrayTP<double, 30>//需要对象

2)  显式实例化

template class ArrayTP<string, 100>;

在这种情况下,虽然没有创建或提及类对象,编译器也将生成类声明(包括方法定义)。和隐式实例化一样,也将根据通用模板来生成具体化。

3)  显式具体化

显式具体化是特定类型(用于替换模板中的泛型)的定义。

template <> class SortedArray(const char *);

21. P583部分具体化

//通用模板

template <class T1, class T2> class Pair {…};

//具体化T2为int

template <class T1>  Pair<T1, int>{…};

关键字template后面的<>声明的是没有被具体化的类型参数,如果都被具体化,则<>为空,这将导致显式具体化。

22. P584成员模板:在模板类内声明模板类或函数模板

23. P586将模板用作模板参数

24. P588-P593模板类和友元

模板类声明也可以有友元。模板的友元分3类:

非模板友元,友元本身不是模板函数,而只是使用了隐式实例化的模板类作为参数。

约束模板友元,类的每一个具体化都获得匹配的友元,友元的类型取决于具体化的类型。在类声明外面声明友元函数模板。

非约束模板友元,友元的每一具体化都是类的所有具体化的友元。在类声明里面声明友元函数模板。

C++ primer plus读书笔记——第14章 C++中的代码重用的更多相关文章

  1. 《C++ Primer Plus》读书笔记之十二—C++中的代码重用

    第14章 C++中的代码重用 1.C++代码重用方法:公有继承.使用本身是另一个类的对象的类成员(这种方法称为包含.组合或层次化).私有或保护继承.类模板等. 2.模板特性意味着声明对象时,必须指定具 ...

  2. 《C++ Primer Plus》第14章 C++中的代码重用 学习笔记

    C++提供了集中重用代码的手段.第13章介绍的共有继承能够建立is-a关系,这样派生类可以重用基类的代码.私有继承和保护继承也使得能够重用基类的代码,单建立的是has-a关系.使用私有继承时,积累的公 ...

  3. SQL Server2012 T-SQL基础教程--读书笔记(1-4章)

    SQL Server2012 T-SQL基础教程--读书笔记(1-4章) SqlServer T-SQL 示例数据库:点我 Chapter 01 T-SQL 查询和编程背景 1.3 创建表和定义数据的 ...

  4. C primer plus 读书笔记第三章

    本章的标题是数据和C,主要内容是介绍数据类型中的整数类型和浮点数类型. 本章的第一段代码 #include <stdio.h> int main(void) { float weight; ...

  5. C++ primer plus读书笔记——第12章 类和动态内存分配

    第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...

  6. C++ primer plus读书笔记——第17章 输入、输出和文件

    第17章 输入.输出和文件 1. 对键盘进行输入缓冲可以让用户在将输入传输给程序之前返回并更正.C++程序通常在用户按下回车键时刷新输入缓冲区. 2. 一些I/O类 streambuf类为缓冲区提供了 ...

  7. C++ primer plus读书笔记——第16章 string类和标准模板库

    第16章 string类和标准模板库 1. string容易被忽略的构造函数: string(size_type n, char c)长度为n,每个字母都为c string(const string ...

  8. C++ primer plus读书笔记——第15章 友元、异常和其他

    第15章 友元.异常和其他 1. 友元类的所有方法都可以访问原有类的私有成员和保护成员.另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元.哪些函数.成员函数.或类为友元是由类定义的, ...

  9. C++ primer plus读书笔记——第13章 类继承

    第13章 类继承 1. 如果购买厂商的C库,除非厂商提供库函数的源代码,否则您将无法根据自己的需求,对函数进行扩展或修改.但如果是类库,只要其提供了类方法的头文件和编译后的代码,仍可以使用库中的类派生 ...

随机推荐

  1. Bonuses on a Line Gym - 102569B

    题目链接:https://vjudge.net/problem/Gym-102569B 题意:数轴上有N个点,从0出发最多走t步问最多经过几个点. 思路:分开存负数点和整数点,然后枚举每个端点,某个点 ...

  2. Git代码版本控制流程

    我们的项目使用Git作为代码仓库.和版本控制工具. Git有几种Workflow,来管理代码版本变更流程,我们采用Gitflow Workflow流程. Gitflow Workflow,采用了mas ...

  3. 配置docker的pdflatex环境

    技术背景 Latex在文档撰写方面是不可或缺的工具,尤其是在写文章方面,是必须要用到的文字排版工具.但是latex的环境部署并不是一个特别人性化的操作,尤其是在各种不同的平台上操作是完全不一样的,还经 ...

  4. js 日期加减

    加: console.log(moment().format("YYYY-MM-DD HH:mm:ss")); //当前时间 console.log(moment().add(10 ...

  5. Apache SkyWalking 告警配置指南

    Apache SkyWalking Apache SkyWalking是分布式系统的应用程序性能监视工具(Application Performance Management,APM),专为微服务.云 ...

  6. 幻灯片放映模式切换windows terminal背景图片

    目录 幻灯片放映模式切换windows terminal背景图片 脚本功能 开发需求 使用技术 操作说明 使用示例 查看帮助 输入参数使用 脚本详情 引用参考 幻灯片放映模式切换windows ter ...

  7. 你真的了解Innodb存储引擎?

    前言 前几篇记录了如何查看SQL执行计划.数据库事务相关的知识点 除了这两个,数据库还有两个是非常重要的,必须要考的 就是存储引擎和索引 今天先记录以下InnoDB存储引擎相关的知识点 MySQL存储 ...

  8. [Fundamental of Power Electronics]-PART II-8. 变换器传递函数-8.4 变换器传递函数的图形化构建

    8.4 变换器传递函数的图形化构建 第7章推导出的buck变换器小信号等效电路模型在图8.55中再次给出.让我们用上一节的图解方法来构造该变换器的传递函数和端阻抗. Fig. 8.55 Small-s ...

  9. JVMGC+Spring Boot生产部署和调参优化

    一.微服务开发完成,IDEA进行maven clean和package 出现BUILD SUCCESS说明打包成功 二.要求微服务启动时,配置JVM GC调优参数 p.p1 { margin: 0; ...

  10. 201871010110-李华 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业要求 我的课程学习目标 (1)理解并掌握代码风格及设计规范:(2)通过任务3进行协作开发,尝试进行代码复审,在进行同伴复审的过程中体会结对 ...