继承和动态绑定与数据抽象一起成为面向对象编程的基础。

模板使我们能够编写独立于具体类型的泛型类和泛型函数。

第15章 面向对象编程

面向对象编程基于三个基本概念:数据抽象、继承和动态绑定。在C++中,用类进行数据抽象,用派生类从一个类继承另一个类:派生类继承基类的成员。动态绑定使编译器能够在运行时决定是使用基类中定义的函数还是派生类中定义的函数。

继承和动态绑定在两个方面简化了我们的程序:能够容易地定义与其他类相似但又不相同的新类,能够更容易地编写忽略这些相似类型之间区别的程序。


面向对象编程的关键思想是多态性。
在C++中,多态性仅用于通过继承而相关联的类型的引用或指针。

派生类能够继承基类定义的成员,派生类可以无须改变而使用那些与派生类型具体特性不相关的操作,派生类可以重定义那些与派生类型相关的成员函数,将函数特化,考虑派生类型的特性。

在C++中,基类必须指出希望派生类重定义哪些函数,定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。

通过动态绑定我们能够编写程序使用继承层次中任意类型的对象,无须关心对象的具体类型。使用这些类的程序无须区分函数是在基类还是在派生类中定义的。
在C++中,通过基类的引用(或指针)调用虚函数时,发生动态绑定。引用(或指针)既可以指向基类对象也可以指向派生类对象,这一事实是动态绑定的关键。

保留字 virtual 的目的是启动动态绑定。保留字 virtual 只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上。

派生类可以访问基类的 public 成员而不能访问 private 成员。protected 成员可以被派生类对象访问但不能被该类型的普通用户访问。(注意:这里都是访问2字,不是继承)

派生类只能通过派生类对象访问其基类的 protected 成员,派生类对其基类类型对象的 protected 成员没有特殊访问权限。

派生类型必须对想要重定义的每个继承成员进行声明。

1、派生类对象包含基类对象作为子对象。
2、派生类中的函数可以使用基类的成员。
3、用作基类的类必须是已定义的。
4、基类本身可以是一个派生类。
5、如果需要声明(但并不实现)一个派生类,则声明包含类名但不包含派生列表。

要触发动态绑定,必须满足两个条件:第一,只有指定为虚函数的成员函数才能进行动态绑定,成员函数默认为非虚函数,非虚函数不进行动态绑定;第二,必须通过基类类型的引用或指针进行函数调用。

基类类型的引用或指针可以引用基类类型对象,也可以引用派生类型对象。
任何可以在基类对象上执行的操作也可以通过派生类对象使用。

友元关系不能继承。基类的友元对派生类的成员没有特殊访问权限。

如果基类定义了 static 成员,则整个继承层次中只有一个这样的成员。无论从基类派生出多少个派生类,每个 static 成员只有一个实例。

构造函数和复制控制成员不能继承,每个类定义自己的构造函数和复制控制函数。

一个类只能初始化自己的直接基类。直接基类就是在派生列表中指定的类。

在复制控制成员中,只有析构函数应定义为虚函数,构造函数不能定义为虚函数。
即使析构函数没有工作要做,继承层次的根类也应该定义一个虚析构函数。

与基类成员同名的派生类成员将屏蔽对基类成员的直接访问。

纯虚函数:纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。在函数形参表后面写上
=0 以指定纯虚函数。

含有(或继承)一个或多个纯虚函数的类抽象基类,除了作为抽象基类的派生类的对象的组成部分,不能创建抽象类型的对象。

将派生类对象复制到基类对象时,派生类对象将被切掉。

C++中面向对象编程的一个颇具讽刺意味的地方是,不能使用对象支持面向对象编程,相反,必须使用指针或引用。

C++中可以通过定义句柄类来存储和管理基类指针。

因为派生类对象包含基类部分,所以可以将派生类型的引用或指针转换为基类类型的引用或指针。

第16章 模板与泛型编程

所谓泛型编程就是以独立于任何特定类型的方式编写代码。

函数模板是一个独立于类型的函数,可作为一种方式,产生函数的特定类型版本。

模板定义以关键字 template 开始,后接模板形参表,模板形参表是用尖括号括住的一个或多个模板形参的列表,形参之间以逗号分隔。例如:

template <typename T>
int compare(const T &v1, const T &v2)
{
if (v1<v2) return -1;
if (v2<v1) return 1;
}

可以给模板形参赋予的唯一含义是区别形参是类型新参还是非类型形参。如果是类型形参,我们就知道该形参表示未知类型,如果是非类型形参,我们就知道它是一个未知值。

类模板成员函数的定义具有如下形式:

1、必须以关键字 template 开头,后接类的模板形参表。

2、必须指出它是哪个类的成员。

3、类名必须包含其模板形参。

形式如下:

template <class T> ret-type Queue<T>::member-name



类模板的指针定义不会对类进行实例化,只有用到这样的指针时才会对类进行实例化。

非类型模板实参必须是编译时常量表达式,不能用变量作模板实参。

<C++Primer>第四版 阅读笔记 第四部分 “面向对象编程与泛型编程”的更多相关文章

  1. C++Primer第5版学习笔记(四)

    C++Primer第5版学习笔记(四) 第六章的重难点内容         你可以点击这里回顾第四/五章的内容       第六章是和函数有关的知识,函数就是命名了的代码块,可以处理不同的情况,本章内 ...

  2. C++ Primer 第四版阅读笔记

    阅读笔记 初始化 变量定义指定了变量的类型和标识符,也可以为对象提供初始值.定义时指定了初始值的对象被称为是 已初始化的.C++ 支持两种初始化变量的形式:复制初始化和 直接初始化.复制初始化语法用等 ...

  3. <C++Primer>第四版 阅读笔记 第一部分 “基本语言”

    之前阅读时没有及时总结,现在慢慢补上. 第1章 快速入门 main 函数在很多方面都比较特别,其中最重要的是每个C++程序必须含有 main 函数,且 main 函数是(唯一)被操作系统显示调用的函数 ...

  4. <C++Primer>第四版 阅读笔记 第三部分 “类和数据抽象”

    类定义了数据成员和函数成员:数据成员用于存储与该类类型的对象相关联的状态:而函数成员则负责执行赋予数据意义的操作. 第12章 类 一个类可以包含若干公有的.私有的和受保护的部分:在public部分定义 ...

  5. <C++Primer>第四版 阅读笔记 第二部分 “容器和算法”

    泛型算法中,所谓"泛型(generic)"指的是两个方面:这些算法可作用于各种不同的容器类型,而这些容器又可以容纳多种不同类型的元素. 第九章 顺序容器 顺序容器的元素排列次序与元 ...

  6. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十四)之Type Information

    Runtime type information (RTTI) allow you to discover and use type information while a program is ru ...

  7. C++Primer第5版学习笔记(三)

    C++Primer第5版学习笔记(三) 第四/五章的重难点内容           你可以点击这里回顾第三章内容       因为第五章的内容比较少,因此和第四章的笔记内容合并.       第四章是 ...

  8. C++Primer第5版学习笔记(一)

    C++Primer第5版学习笔记(一) 第一.二章的重难点内容        这个笔记本主要记录了我在学习C++Primer(第5版,中文版)的过程中遇到的重难点及其分析.因为第一.二章都比较简单,因 ...

  9. Hadoop阅读笔记(四)——一幅图看透MapReduce机制

    时至今日,已然看到第十章,似乎越是焦躁什么时候能翻完这本圣经的时候也让自己变得更加浮躁,想想后面还有一半的行程没走,我觉得这样“有口无心”的学习方式是不奏效的,或者是收效甚微的.如果有幸能有大牛路过, ...

随机推荐

  1. laravel项目安装debugbar

    在github上有laravel项目的debugbar,可以查看项目的页面引用.变量.数据库使用.内存和反应时间等,貌似是一个还不错的小工具,效果如下: 安装地址:https://github.com ...

  2. 【转】 谈谈C++中的swap函数

    1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T c(a) ...

  3. 【转】101个MySQL调试和优化技巧

    MySQL是一个功能强大的开源数据库.随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它的极限.这里是101条调节和优化MySQL安装的技巧.一些技巧是针对特定的安装环境的,但这些思 ...

  4. CLR VIA C#: 基元类型、 引用类型 和 值类型

    一.基元类型 . 引用类型 和 值类型的区别: 1.基元类型(primitive type):编译器直接支持的数据类型: 基元类型 直接映射到 FCL 中存在的类型. C# 小写是基元类型,例如:st ...

  5. mongodb学习(六)索引

    准备工作: 先插入100万条数据 for(i=0;i<=1000000;i++){ db.users.insert({ "i":i, "username" ...

  6. Use Wireshark to capture loopback traffic without a loopback adapter (转)

    Use Wireshark to capture loopback traffic without a loopback adapter If you’ve ever used Wireshark f ...

  7. 创业类网站建设日志1——搭建服务器svn以及前端开发环境

    1.需要在linux环境的服务器下搭建node和npm还有Grunt,所以先需要一个叫putty的工具连接服务器命令行终端 2.双击putty工具,在HostName一栏输入项目服务器地址:172.1 ...

  8. JAVA 遍历文件夹下的所有文件(递归调用和非递归调用)

    JAVA 遍历文件夹下的所有文件(递归调用和非递归调用) 1.不使用递归的方法调用. public void traverseFolder1(String path) { int fileNum = ...

  9. 高尔夫 之 TEE

    黑色:男子职业选手蓝色:男子业余高手.女子职业选手白色:男子初学球手.老年球手.女子业余高手红色:女子选手金色:有的球场做为介于 黑Tee (职业球员)与 蓝Tee (业余高手)之间的Tee 台:有的 ...

  10. IOS 上线问题

    info.plist 是否支持后台位置 音频 Info.plist中添加UIBackgroundModes键值,它包含一个或多个string的值,包括 audio:在后台提供声音播放功能,包括音频流和 ...