第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. 关于java的访问修饰符权限

    作用域    public protected default private  同一个类   yes     yes      yes      yes 同一个包   yes     yes    ...

  2. 输出质数(Java)

    输出质数 一.什么是质数 质数又称素数.一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数,否则称为合数(规定1既不是质数也不是合数). 二.代码实现 1.输出100以内的质数 i ...

  3. POJ1562_Oil Deposits(JAVA语言)

    思路:bfs.水题,标记下计数就完了. Oil Deposits Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22928 ...

  4. SqlServer视图的创建与使用

    SqlServer系列之视图的创建与使用: 什么是视图? 视图的概述 在数据查询中,可以看到数据表设计过程中,考虑到数据的冗余度低.数据一致性等问题,通常对数据表的设计要满足范式的要求,因此也会造成一 ...

  5. 用 customRef 做一个防抖函数,支持 element 等UI库。

    这几天学习Vue的官网,看到 customRef 提供了一个例子,研究半天发现这是一个防抖函数,觉得挺好,于是把这个例子扩展了一下,可以用于表单子控件和查询子控件. 需求 v-model 基于 ele ...

  6. du和df的统计结果为什么会不一样?

    du和df的统计结果为什么会不一样? 今天有个人问我du和df的统计结果为什么会不同,接下来我们分析一下. 我们常常使用du和df来获取目录或文件系统已占用空间的情况.但它们的统计结果是不一致的,大多 ...

  7. shell的配置文件

    1. bash shell 的配置文件 bash shell的配置文件很多,可以分成下面类别 1.1 按生效范围划分两类 全局配置:针对所有用户皆有效 /etc/profile /etc/profil ...

  8. C++并发与多线程学习笔记--future成员函数、shared_future、atomic

    std::future的其他成员函数 std::shared_future 原子操作.概念.基本用法 多线程主要是为了执行某个函数,本文的函数的例子,采用如下写法 int mythread() { c ...

  9. 从零搭建一个IdentityServer——会话管理与登出

    在上一篇文章中我们介绍了单页应用是如何使用IdentityServer完成身份验证的,并且在讲到静默登录以及会话监听的时候都提到会话(Session)这一概念,会话指的是用户与系统之间交互过程,反过来 ...

  10. [模拟]P1046 陶陶摘苹果

    陶陶摘苹果 ## 题目描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试 ...