深入理解C++对象模型之构造函数

一、前言

    学习C++的同学一般都知道有构造函数这个东西,我相信很多同学的理解就是构造函数是用来初始化类成员的,是的,构造函数的本质确实是这样的,但很多同学会有以下两个误解:

        (1)任何class如果没有定义任何构造函数,编译器就会帮你自动生成一个;

        (2)编译器用合成出来的默认构造函数会“Class内的每一个data member”;

先不说这两个观点对不对,但至少他不严谨。


二、构造函数与默认构造函数

    这里首先引出C++Primer里面的关于构造函数的介绍:构造函数的任务是初始化类对象的数据成员,无论什么时候只要class的对象被创建,就会执行构造函数。我的理解是这里所说的构造函数是User Constructor Function,即用户定义的构造函数,与其相对应的还有一种叫做默认构造函数。在网上看到关于默认构造函数的定义为:可以不用实参进行调用的构造函数,其包括两种情况:(1)没有带明显形参的构造函数;(2)提供了默认实参的构造函数。

    这里之所以要介绍默认构造函数,是因为用户可以自己定义一个默认构造函数,而编译器也可以为我们合成一个默认构造函数,其实编译器合成的构造函数确实是都不带明显形参的,因此我们经常把编译器合成的构造函数称为“合成默认构造函数”


三、编译器需要的构造函数和程序需要的构造函数

    用户定义一个以下类和它的构造函数

class A
{
public:

private:
    int a;
    int b;
};

class A没有定义构造函数,按照前言中,大多数同学的第一个误解,即任何class如果没有定义默认构造函数,编译器就会帮你自动生成一个,OK,那么生成一个默认构造函数干什么呢?同学的潜意识里是要求编译器用生成的这个构造函数去初始化成员变量a和b。那这么说是不是就能用这个类去实例化一个对象呢?因为只有实例化对象的时候才需要调用构造函数啊,这才是你自以为的编译器合成的构造函数的用武之地啊。下面在VS2010IDE中进行验证,结果是这样的:

#include <iostream>
using namespace std;
class A
{
public:

public:
    int a;
    int b;
	
};

void main()
{
    A obj1;
    cout<<"obj1.a = "<<obj1.a<<endl;
}


    What?为什么结果是这样的呢?对象obj1没有被初始化?不是说编译器会生成一个默认构造函数来初始化他的成员变量吗?其实实际上编译器并没有合成默认构造函数,因为你所谓的编译器会合成一个构造函数来初始化其成员变量,那是你认为,自以为的,并不是编译器以为的,也就不是编译器需要的,而是程序的本身需要,你要访问对象obj1的成员,程序当然需要先对其初始化,但是程序需要并不等于编译器需要

    因此,这就可以推翻同学们的第一个误解,很多时候编译器并没有帮你生成默认构造函数,即使你没有定义任何构造函数,因为这不是编译器的必须工作(尽管编译器背着你干了很多有利于你的事情,但它也不是傻子,不是它的事情,它肯定不会干)

    那既然编译器不会帮你合成默认构造函数,那为什么有很多人这样说呢?我想这应该是断章取义的结果。在《深入理解C++对象模型》中,侯捷大师引用C++ standard很明确的给了我们答案。第一个说明是:对于Class X,如果没有任何用户声明的构造函数,那么会有一个默认构造函数被隐式声明出来,……一个被隐式声明的默认构造函数是trivial(浅薄无能的、没啥用的)构造函数。这就和同学的第一点误解有很大的相似性,但仅仅是相似,而完全不同,因为这里说的只是声明出一个trivial的构造函数,并不是为误解了的会合成出一个默认构造函数,声明了并不代表一定要合成(即定义)

    那么是不是都不会合成呢?也不是,候老师给的解答是:默认构造函数只有在需要的时候被编译器产生(合成、定义)出来。关键字眼是“在需要的时候”,被谁需要?那当然是被编译器需要,那什么情况下编译器才是需要的呢?就是下面四种情况:

    (1)带有默认构造函数的类成员对象。即如果一个Class A没有定义任何构造函数,但它含有一个Class B对象成员,而Class B有默认构造函数,那么Class A的默认构造函数就是被编译器需要的,因此编译会合成Class A的默认构造函数。这里Class A和B分别定义如下

class B
{
public:
    B()
    {
        m=1;
        n=2;
    }
private:
    int m;
    int n;
};
class A
{
public:
public:
    int a;
    int b;
    B obj2;
};
现在再访问Class A的对象,如

void main()
{
	A obj1;
	cout<<obj1.a<<endl;
}
不会再出现Class obj1未定义的错误,但是输出的结果为未知数,比如我的运行结果是:a=-858999460;这是一个未定义的整数,为什么呢?程序没有报错,说明Class A的对象obj1已经正确被构造,也说明编译器已经为我们合成了默认构造函数,初始化了Class B的对象obj2,但为什么没有初始化自己的成员对象a和b呢? 还是那句话,编译器只做自己该做的事情,不是它的事情它不会做,而成员变量初始化时程序需要的,则应该有程序员来完成,就算编译器合成了一个有用的默认构造函数,它也不会初始化变量a和b,它只负责调用Class B的默认构造函数来初始化Class B的对象obj2。如下面的程序执行

void main()
{
    A obj1;
    cout<<"obj1.a = "<<obj1.a<<endl;
    cout<<"obj2.m = "<<obj1.obj2.m<<endl;
}
结果为:(能充分说明上述的分析)

上述结论,也能推翻同学们对前言中的第二个误解,编译器用合成出来的默认构造函数会“Class内的每一个data member”,其实编译器它只做自己该做的事情。

    (2)带有默认构造函数的基类。如果一个没有任何构造函数的Class是继承于一个带有默认构造函数的基类,那么派生类的默认构造函数也是被编译器需要的,编译器需要为用户合成一个默认构造函数。

        因为构造子类之前需要先构造基类,即使派生类没有定义任何构造函数,编译器也会合成一个默认构造函数,用来调用基类的默认构造函数。

    (3)带有虚函数的Class。即如果一个Class定义了虚函数,那么编译器也要合成默认构造函数。

    (4)虚拟继承体系中的派生类,编译器也需要合成默认构造函数。

        对于情况(3)和(4),编译器之所以要生成默认构造函数,是因为编译器需要在合成的默认构造函数中对虚函数和虚拟继承机制进行支持,即需要设定或者重置虚函数表或者虚基类指针。



  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在国际象棋中,学会如何移动棋子只能算是入门:要想掌控整个棋局,我们必须了解自己所下的每一步棋后的策略和战术。在C++中也同样如此。掌握正确的策略可以帮助我们避免常见的陷阱,并提高我们的工作效率。在本书中,C++专家Rob Murray就与我们分享了他宝贵的经验和建议,以帮助初中级C++程序员得到进一步的提高。 在本书中,作者大量采用了实际开发中的代码来作为示例,向读者展示了那些有用的编程策略,并对那些有害的做法进行了警示。为了帮助读者更好地理解,在书中的每一章结束前,在该章中被介绍过的主要内容都被放到了一个列表中,此外,书中还给出了一些问题来激励读者们进行更多的思考和讨论。 本书在一开始就向我们讲解了如何为我们的设计选择正确的抽象,提示我们注意抽象和现实之间的区别。然后,我们就将学到如何将已得到的抽象转化成一个(或多个)C++中的类,期间进行的讨论所涵盖的范围上至高层的设计策略,下至底层的接口和实现细节。 接下来本书对单继承和多重继承进行了深入的探索。一开始书中会给出一个关于它们应该用在设计的什么地方的讨论,然后就是一些详细的示例代码,用来向我们演示如何在实践中使用这些概念。对于 mulu 代译者序 序 第0章 简介 0.1 关于示例代码 0.2 本书的组织 0.3 问题 0.4 语言规则 第1章 抽象 1.1 有关电话号码的抽象模型 1.2 抽象模型间的关系 1.3 请考虑边界条件 1.4 使用CRC卡片来辅助设计 1.5 小结 1.6 问题 第2章 类 2.1 构造函数 2.2 赋值 2.3 公用数据 2.4 隐式类型转换 2.5 操作符重载:成员或非成员? 2.6 重载、缺省值以及省略符 2.7 Const 2.8 返回值为引用 2.9 静态对象的构造 2.10 小结 2.11 问题 第3章 句柄 3.1 一个String类 3.2 使用计数器来避免多份拷贝 3.3 避免进行重编译:Cheshire Cat 3.4 使用句柄来隐藏设计 3.5 多种实现 3.6 作为对象的句柄 3.7 综述 3.8 小结 3.9 问题 第4章 继承 4.1 is-a关系 4.2 公有继承 4.3 私有继承 4.4 保护型继承 4.5 与基类抽象的一致性 4.6 纯虚函数 4.7 有关继承的细节和陷阶 4.8 小结 4.9 问题 第5章 多重继承 5.1 作为交集的多重继承 5.2 虚基类 5.3 一些有关多重继承的细节问题 5.4 小结 5.5 问题 第6章 考虑继承的设计 6.1 被保护的接口 6.2 我们的设计是否应该考虑到继承? 6.3 一些为继承所做的设计的例子 6.4 结论 6.5 小结 6.6 问题 第7章 模板 7.1 模板类Pair 7.2 一些有关模板的细节 7.3 模板的实例化 7.4 智能指针 7.5 作为模板参数的表达式 7.6 模板函数 7.7 小结 7.8 问题 第8章 模板的高级用法 8.1 使用了模板的容器类 8.2 示例:Block 8.3 有关Block的设计细节 8.4 带有迭代器的容器:List 8.5 迭代器的设计细节 8.6 性能上的考虑 8.7 对模板参数的限制 8.8 模板特化 8.9 小结 8.10 问题 第9章 重用 9.1 发现和获得 9.2 健壮性 9.3 内存管理 9.4 可选的内存分配方案 9.5 传递参数给operator new 9.6 管理外部资源 9.7 寻找有关内存的bug 9.8 名字冲突 9.9 性能 9.10 不要去猜想,而应该度量! 9.11 算法 9.12 动态内存分配中的瓶颈 9.13 内嵌 9.14 Tiemann法则 9.15 小结 9.16 问题 第10章 异常 10.1 一个负面的声明 10.2 为什么需要异常? 10.3 一个异常的例子 10.4 异常只应该用来表述异常情况 10.5 理解异常 10.6 责任评估 10.7 设计异常对象 10.8 小结 10.9 问题 第11章 向C++移植 11.1 选择使用C++ 11.2 采用C++ 11.3 设计和实现 11.4 开发一个坚实的基础 11.5 相关的思考 11.6 小结 11.7 问题
本教程共分为5个部分,第一部分是C语言提高部分,第二部分为C++基础部分,第三部分为C++进阶部分,第四部分为C、C++及数据结构基础部分,第五部分为C_C++与设计模式基础,内容非常详细. 第一部分 C语言提高部分目录 01_初学者的企业用人标准寻找引言 02_socketclient_api模型的抽象_初学者应知的标准_传智扫地僧 03_本套视频总体课程简介 04_就业班课程总体简介_课堂答疑 05_初学者建立信心 06_学员学习标准_排序及问题抛出 07_数组做函数参数退化问题剖析_传智扫地僧 08_数据类型基础提高 09_数据类型引申和思考 10_变量本质剖析和内存四区模型引出_传智扫地僧 11_c的学习重理解到位_对初学者_传智扫地僧 12_直接通过内存标号操作内存空间_课堂答疑 13_中午课程回顾 14_内存四区基本原理_全局区案例理解 15_内存四区_堆栈案例理解 16_课堂答疑_理解指针的关键关键在内存 17_vs20102013上配置#系列快捷方式 18_栈的属性和buf地址增长方向是两个不同的概念 19_函数调用模型_主调函数和被调用函数 20_课堂答疑_函数调用流程入栈出栈过程 21_指针也是一种数据类型_基础 22_指针也是一种数据类型_强化_传智扫地僧 源码及文档 01_课程回顾 02_作业题强化和野指针 03_向null地址copy数据和不断改变指针指向强化 04_有关字面量 05_间接赋值从0级指针到1级指针 06_间接赋值从1级指针到2级指针_技术推演_传智扫地僧 07_间接赋值是指针存在的最大意义 08_间接赋值成立的三个条件和应用场景 09_指针学习思路应用清晰起来 10_指针强化3和指针强化4思想讲解 11_字符串的基本操作 12_数组中括号与指针关系和数组名常量指针分析 13_字符串一级指针内存模型_传智扫地僧 14_字符串copy函数技术推演 15_字符串copy函数强化训练_判断null_引入辅助指针变量_传智扫地僧 16_项目开发模型强化_strstr_while模型_重要 17_作业考试强化 源码及文档 01_上一次课程回顾 02_两头堵模型 03_字符串反转_方法1指针 04_字符串反转_方法2递归逆序(3个点)_传智扫地僧 05_考试题解答和项目开发代码书写手法 06_一级指针易错模型分析_重点 07_C语言中的const知识点总结 08_指针的输入和输出模型 09_课堂答疑_指针所指向内存释放 10_二级指针做输入_第1种内存模型 11_二级指针做输入_第2种内存模型 12_二级指针做输入_第2种内存模型_课堂答疑_多维数组名本质抛砖 13_二级指针做输入_第3种内存模型_传智扫地僧 14_二级指针三种内存模型示意图_传智扫地僧 15_玩转多级指针_传智扫地僧 16_两个辅助指针变量挖字符串测试框架搭建 18_作业 源码及文档 01_课程回顾 02_两个赋值指针变量挖字符训练_第3种内存模型_传智扫地僧 03_多级指针的野指针问题(释放问题)_传智扫地僧 04_学员作业点评_典型错误吸取教训 05_数组类型 06_数组指针类型和定义数组指针变量的3种方法 07_多维数组名本质剖析_传智扫地僧 08_多维数组的【】和多级指针星号转化推演 09_多维数组做函数参数技术推演和退化原因抛出 10_多维数组做函数参数退化总结_ 11_指针数组的应用场景01 12_指针数组自我结束能力(三种表示方法) 13_干活要知道在什么框架之下干活 14_结构体类型和变量定义及基本操作 15_结构体元素做函数参数pk结构指针做函数参数 16_结构体做函数基本操作 17_结构体做函数内存分配指针 18_结构中套一级指针 19_结构体中套二级指针_传智扫地僧 20_作业强化 21_C提高课程_day01-day04_知识体系梳理_传智扫地僧 源码及文档 01_上次课程回顾 02_二级指针三种内存模型综合训练_框架搭建 03_二级指针三种内存模型综合训练_实现 04_二级指针三种内存模型综合训练_典型错误 05_结构体作业点评 06_结构体中的深copy和浅copy 07_结构中的高级话题_偏移量 08_结构中的高级话题_偏移量强化 09_文件操作api基本概念 10_按照字符读写文件 11_按照行方式操作文件 12_按照块的方式操作文件 13_中午课程回顾 14_配置文件读写案例功能介绍 15_配置文件读写案例_接口设计 16_配置文件读写案例_集成框架搭建 17_配置文件读写案例_读配置项实现 18_配置文件读写案例_写和修改接口实现 19_文件加密案例_思路分析 20_文件加密案例_文件搬运实现 21_文件加密案例_文件加密功能集成 22_文件加密案例_文件加密实现 23_作业 24_学员二级指针代码bug调试_传智扫地僧 源码及文档 01_课程回顾 02_解密作业 03_指针用法杂项 04_再谈多级指针做输出_传智扫地僧 05_动态库的基本概念和使用 06_动态库测试环境和调试环境搭建 07_socketclient动态库函数_初始化实现wmv 08_socketclient动态库函数_发送接受释放实现wmv 09_socketclient动态库_第二套api函数_传智扫地僧 10_socketclient动态库_日志功能集成 11_项目中检索内存泄漏使用和基本原理 12_动态库基本知识和环境调试注意 13_动态库内存释放问题 源码及文档 01_上一次课程回顾 02_链表热身_结构体中套元素和指针 03_结构体数据类型的嵌套定义和函数的嵌套调用是两个不同的概念 04_静态链表及局限性 05_链表的分类和链表的辅助指针变量 06_链表api函数搭建 07_链表的创建和打印 08_链表的插入操作和辅助指针变量分析_传智扫地僧 09_链表的删除和销毁 10_链表的逆置_传智扫地僧 11_链表的逆置_课堂答疑 12_课堂答疑pheadnextnext 13_中午课程回顾 14_传统链表和非传统链表 15_链表的技术体系推演 16_通用链表库集成和测试 17_C提高课程_day05-day07_知识体系梳理_传智扫地僧 源码及文档 第二部分 C++基础目录 01_C++基础课程的安排和需要持之以恒的学习态度 02_简单的C++程序helloworld 03_用面向过程和面向对象方法求解圆形面积_类和对象的关系思考_传智扫地僧 04_类中不写成员函数易犯错误模型 05-易犯错误模型-为什么需要成员函数(补充资料)-传智扫地僧 06_课堂答疑类中写成员函数_调用的时才会执行 07_程序设计方法发展历程 08_C语言和C++语言的关系_工作经验分享 09_namespace和iotream 10_实用性加强_register增强_检测增强 11_struct关键字类型增强 12_c++类型类型检查加强 13_新增数据类型bool类型 14_中午课程回顾 15_c++中的三目运算符_传智扫地僧 16_const的基础和const符号表机制探究_传智扫地僧 17_const和#define的对比_传智扫地僧 18_引用的基础知识(定义和函数参数) 19_复杂数据类型引用做函数参数__传智扫地僧 20_引用的本质剖析_传智扫地僧 21_函数返回值是引用(当左值右值)_传智扫地僧 源码及文档 01_上一次课程复习 02_指针的引用_传智扫地僧 03_常引用 04_inline内联函数 05_函数参数相关扩展 06_函数重载 07_函数重载和函数指针在一起 08_中午课程回顾 09_c++学习路线和c++基础课程学习标准_传智扫地僧 10_类的封装和访问控制 11_struct和class关键字区别 12_类的声明和类的实现分开 13_面向过程向面向对象转变案例1 14_面向过程向面向对象转变案例2 15_面向过程向面向对象转变案例3 16_作业 17_C++基础课程day01-day02_知识体系梳理_传智扫地僧 源码及文档 01_上一次课程回顾 02_构造和析构的基础知识 03_构造和析构的用途演示 04_构造函数的调用(无参数和有参构造)_传智扫地僧 05_课堂答疑对象的初始化和对象的赋值是两个不同的概念 06_为什么需要构造和析构函数 07_copy构造函数的调用时机1和2 08_课堂答疑 09_copy构造函数调用时机3_传智扫地僧 10_copy构造函数调用时机4_函数返回值是匿名对象_传智扫地僧 11_copy构造函数调用时机4_函数返回值是匿名对象的去和留的剖析_传智扫地僧 12_构造和析构的重点整理 13_构造和析构总结 14_中午课程复习 15_构造函数的调用规则研究 16_浅拷贝问题抛出 17_浅拷贝问题分析_传智扫地僧 18_浅拷贝问题解决_深拷贝_显示编写拷贝构造函数 19_深拷贝和浅拷贝_默认的等号操作符也是浅拷贝_传智扫地僧 20_构造函数的初始化列表 21_强化训练1_构造和析构调用顺序 22_强化训练2_匿名对象生命周期 23_强化训练3_构造中调用构造(产生匿名对象)_传智扫地僧 24_new和delete的基本语法 25_new和delete的深入分析 26_静态成员变量和静态成员函数 27_C++面向对象模型初探_传智扫地僧 28_this指针 29_作业 源码及文档 01_上一次课程回顾 02_const修饰的是谁_传智扫地僧 03_this的const修饰课堂答疑 04_全局函数pk成员函数(返回元素,引用,星号this) 05_强化训练数组类_类的设计和测试程序 06_强化训练数组类_类的实现和测试 07_友元函数 08_友元类 09_运算符重载入门基础推演_传智扫地僧 10_运算符重载语法理论知识介绍 11_中午课程回顾 12_成员函数和友元函数完成二元运算符重载 13_成员函数和友元函数完成一元运算符重载(前置) 14_成员函数和友元函数完成一元运算符重载(后置) 15_友元函数实现左移右移操作符重载(函数返回值当左值需返回引用)_传智扫地僧 16_友元函数实现操作符重载知识总结 17_重载等号操作符_传智扫地僧 18_数组类小案例_操作符重载需求 19_数组类小案例_重载[]_传智扫地僧 20_数组类小案例_重载等号_传智扫地僧 21_数组类小案例_重载==和!= 22_作业 源码及文档 01_上一次课程的回顾 02_()运算符重载 03_逻辑与和逻辑或运算符重载说明 04_课堂答疑_逻辑与和逻辑或运算符重载 05_MyString类案例_构造和析构函数 06_MyString类案例_重载等号和数组操作符_传智扫地僧 07_MyString类案例_重载左移操作符 08_MyString类案例_重载双等号和不等号 操作符 09_MyString类案例_重载大于和小于操作符 10_MyString类案例_其他技巧 11_MyString类案例_重载右移操作符 12_C++基础课程day03-day05_知识体系梳理 13_作业和考试 源码及文档 01_继承的概念 02_子类可以访问父类的属性和方法 03_派生类的访问控制 04_派生类的访问控制综合训练_传智扫地僧 05_类型兼容性原则_传智扫地僧 06_继承中的构造和析构 07_继承和组合混搭下的构造和析构_传智扫地僧 08_继承中的同名成员变量和同名成员函数 09_继承的static关键字 10_多继承的基本语法 11_二义性和虚继承解决方案 12_中午课程回顾 13_多继承原理抛砖_传智扫地僧 14_多态思想引言 15_类型兼容性原则遇上还是函数重写_面向对象新需求_传智扫地僧 16_多态案例_多态的意义_多态成立的三个条件_传智扫地僧 17_多态案例丰富多彩和多态的理论知识 18_虚析构函数 19_重载重写重定义_问题抛出 20_重载重写重定义_概念分析_传智扫地僧 21_重载重写重定义_课堂答疑_传智扫地僧 文档和源码 01_上一次课程回顾 02_多态原理探究_传智扫地僧 03_证明vptr指针的存在 04_子类的vptr指针是分步初始化的_传智扫地僧 05_面试题强化_多态相关 06_父类指针的步长和子类指针的步长不一样 07_课堂答疑什么时候子类的步长和父类的步长一样 08_抽象类基本语法 09_抽象类在多继承中的应用 10_面向抽象类编程_计算程序员工资 11_中午课程回顾 12_信息系统框架集成第三方产品案例_背景和需求 13_信息系统框架集成第三方产品案例_编码实现分析_传智扫地僧 14_信息系统框架集成第三方产品案例_socket抽象类和框架搭建__传智扫地僧 15_信息系统框架集成第三方产品案例_框架实现第一个socket类厂商实现 16_信息系统框架集成第三方产品案例_第二个socket类厂商实现 17_信息系统框架集成第三方产品案例_加解密抽象类和加解密厂商类实现 18_信息系统框架集成第三方产品案例_集成测试加密厂商和socket厂商入围 19_信息系统框架集成第三方产品案例_集成框架变成类方式_传智扫地僧 20_信息系统框架集成第三方产品案例_几个重要的面向对象思想_传智扫地僧 21_作业 文档和源码 01_上一次课程回顾 02_数组指针语法梳理 03_函数指针语法梳理_传智扫地僧 04_函数指针做函数参数思想剖析_传智扫地僧 05_函数指针的正向调用案例 06_C动态库升级成框架案例_项目需求和基本思想_传智扫地僧 07_C动态库升级成框架案例_开发环境搭建 08_C动态库升级成框架案例_方法1动态库中直接添加回调函数_传智扫地僧 09_C动态库升级成框架案例_方法2把回调函数缓存到动态库_编写 10_C动态库升级成框架案例_方法2把回调函数混存到动态库_测试 11_C++基础课程day06-day08_知识体系梳理 文档和源码 第三部分 C++进阶部分目录 01_上一次课程知识点_梳理 02_函数模板为什么和函数模板语法基础 03_课堂答疑_遇到莫名其妙的问题_重新编译 04_函数模板当函数参数 05_普通函数和模板函数区别_传智扫地僧 06_函数模板和函数重载在一起(调用规则研究)_传智扫地僧 07_函数模板机制探究上 08_函数模板机制探究下_传智扫地僧 09_课堂答疑_二次编译 10_类模板语法_数据类型和算法的分离_抛砖 11_单个类模板基本语法 12_类模板_派生_普通类语法 13_类模板_派生_类模板语法 14_中午知识点梳理 15_复数类_所有函数都写在类的内部 16_复数类_所有函数都写在类的外部_上 17_复数类_所有函数都写在类的外部_下 18_复数类_所有函数都写在类的外部(h和cpp分开) 19_类模板中的static关键字 20_案例_数组模板类_需求和类的初步设计 21_案例_数组模板类_测试框架搭建 22_案例_数组模板类_类的实现和测试_传智扫地僧 23_案例_数组模板类_数组元素存储的是类对象思想抛砖_传智扫地僧 24_作业 代码 文档 01_泛型编程_知识点梳理 02_模板数组类_作业讲解和思想强化(数据类型和算法的分离)_传智扫地僧 03_类型转换_static_cast和reinterpret_cast 04_类型转换_dynamic_cast和reinterpret_cast_传智扫地僧 05_类型转换_const_cast 06_异常的基本语法 07_异常机制基本思想梳理 08_栈解旋unwinding 09_异常接口声明 10_异常类型_异常变量的生命周期上 11_异常类型_异常变量的生命周期下_传智扫地僧 12_中午知识点梳理 13_异常的层次结构_传智扫地僧 14_标准异常库 15_流类库结构 16_标准IO_输入api_上 17_标准IO_输入api_下 18_标准IO输出_api和格式控制 19_文件的读写 代码 文档 01_stl总体课程安排 02_stl容器算法迭代器三大概念入门 03_stl理论知识_基本概念串讲 04_stl的string的典型操作1_初始化_遍历_连接_和字符指针转化_查找替换传智扫地僧 05_stl的string的典型操作2_删除和插入 06_stl的string的常用算法 07_vector基本操作_对象创建_头部尾部操作元素_数组方式遍历vector 08_vector的迭代器遍历和迭代器的种类_传智扫地僧 09_vector基本操作_删除和插入_传智扫地僧 10_中午知识点回顾 11_deque容器基本操作 12_stack栈模型 13_queue模型 14_list容器模型基本操作 15_优先级队列priority_queue基本操作 16_set容器_插入_遍历_基本数据类型比较 17_set容器_自定义数据类型排序(仿函数应用)_insert判断返回值(pair的使用)_传智扫地僧_ 18_set容器_find查找_equal_range(pair的使用)_传智扫地僧_ 19_multiset容器基本操作_ 文档 源码 01_上一次课程知识点回顾 02_map容器基本操作_插入和插入结果判断_传智扫地僧 03_map容器基本操作_查找和查找的异常处理 04_multimap容器案例_按照部门_增删改查员工信息 05_容器的值拷贝语意 06_各个容器特点比较 07_stl算法设计理念_函数对象和函数对象当参数和返回值_传智扫地僧 08_stl算法设计理念_一元函数对象和一元谓词 09_中午课程知识点回顾 10_stl算法设计理念_二元函数对象和二元谓词 11_stl算法设计理念_二元谓词在set集合的应用 12_stl算法设计理念_预定义函数对象和函数适配器1_传智扫地僧 13_stl算法设计理念_预定义函数对象和函数适配器2_案例_传智扫地僧 14_stl容器算法迭代器的设计理念_重要理论思想总结_传智扫地僧 15_stl的算法概念和分类 16_stl算法_foreach和transform基本使用 17_stl算法_foreach和transform算法比较_transform算法源码追踪_传智扫地僧 文档 源码 01_上一次课程复习 02_stl常用算法_查找相关 03_stl常用算法_排序相关 04_stl常用算法_拷贝和替换相关 05_stl常用算法_算法和生成 06_stl常用算法_集合运算 07_STL案例_演讲比赛_比赛介绍和需求分析 08_STL案例_演讲比赛_搭建案例框架_传智扫地僧 09_STL案例_演讲比赛_实现思路分析_传智扫地僧 10_STL案例_演讲比赛_业务函数实现_产生选手和选手抽签 11_STL案例_演讲比赛_业务函数实现_选手比赛_传智扫地僧 12_STL案例_演讲比赛_业务函数实现_比赛晋级结果打印 13_STL课程_知识体系梳理_传智扫地僧 文档 源码 第四部分 01_数据结构课程_学习思路_学习基础 02_数据结构概念_基本概念 03_数据结构概念_逻辑关系_物理结构 04_算法基本概念和大O表示 05_算法的时间复杂度 06_算法的空间复杂度_空间换时间案例 07_课堂答疑_学员思路 08_线性表的理论知识梳理_重点在链表算法和具体数据类型的分离 09_线性表顺序存储设计和实现_环境搭建 10_线性表顺序存储设计和实现_api函数实现1 11_线性表顺序存储设计和实现_api函数实现2_插入算法 12_线性表顺序存储设计和实现_api函数实现3_get和delete 13_线性表顺序存储设计和实现_总结 14_线性表链式存储_设计与实现_框架搭建和链表技术领域推演_传智扫地僧 15_线性表链式存储_设计与实现_api实现_传智扫地僧 16_线性表链式存储_设计与实现_api实现下_传智扫地僧 17_线性表链式存储_总结 18_c++模板链表_类设计和测试框架搭建 19_c++模板链表_类实现 代码 文档 01_数据结构day01_知识点梳理 02_c++链表模板类_思想加强 03_循环链表api熟悉 04_循环链表应用_约瑟夫问题求解 05_循环链表_插入算法分析_传智扫地僧 06_循环链表_删除算法分析 07_循环链表_游标课堂答疑 08_循环链表_api串讲 09_循环链表_api熟悉 10_栈的顺序存储_设计与实现_测试框架搭建 11_中午课程回顾 12_栈模型和链表模型_顺序存储_思想分析_传智扫地僧 13_栈的顺序存储_设计与实现_api实现和调试 14_栈的顺序存储_设计与实现_课堂答疑 15_栈链式存储_设计与实现_测试框架搭建 16_栈链式存储_设计与实现_栈结点转换成链表结点_思想分析_传智扫地僧 17_栈链式存储_设计与实现_api实现_传智扫地僧 18_栈链式存储_设计与实现_内存管理 19_栈的应用案例_就近匹配 20_栈的应用案例_中缀转后缀 21_栈的应用案例_基于后缀表达式的计算_传智扫地僧 22_栈的应用案例_程序讲解 23_树模型抛砖 代码 文档 01_上一次课程_知识点回顾 02_队列顺序存储_设计与实现_测试框架 03_队列顺序存储_设计与实现_api函数的实现 04_队列链式存储_设计与实现_测试框架 05_队列链式存储_设计与实现_api函数实现 06_树的概念_定义_表示法_二叉树转换_树的存储 07_二叉树的概念_定义和性质 08_二叉树的概念_表示法_二叉树遍历 09_中午课程回顾 10_二叉树编程_遍历本质剖析和递归方式遍历_传智扫地僧 11_二叉树编程案例1_求叶子结点的数目 12_二叉树编程案例2和3_求树高度_拷贝二叉树 13_二叉树编程案例_课堂答疑 14_树非递归中序遍历_思想分析 15_树非递归中序遍历_遍历过程演示 16_树非递归中序遍历_实现(stl方式)_传智扫地僧 17_stl栈模型组合容器类对象_思想抛砖 18_创建树思想抛砖 代码 文档 01_上一次课程回顾 02_创建树_先序和中序确定树 03_学习数据结构_常用工具介绍 04_创建树_#号法 05_创建树_#号法编程实践 06_创建树_#号法课堂答疑 07_线索化_概念_过程分析 08_线索化_两个赋值指针变量线索化思想 09_线索化_线索化初始化流程 10_线索化_遍历思想 11_线索化_遍历树时,把结点插入链表中 12_中午课程总结和线索化逆序访问 13_霍夫曼树概念 14_排序_概念 15_排序_选择法 16_排序_插入法 17_排序_冒泡 18_排序_希尔排序 19_排序_希尔排序_分组很重要 20_排序_快速排序 21_排序_归并 22_数据结构课程_知识体系梳理 代码 文档 01_上一次课程知识点回顾 02_递归需要需要掌握的点补充 03_链表类_链式存储_测试 04_链表类_链式存储_api实现 05_链表类_链式存储_课堂答疑 06_栈类_链式存储_api实现 07_队列类_链式存储设计与实现_api 08_链表类_顺序存储_类设计和测试框架 09_链表类_顺序存储_类api实现 10_栈类_顺序存储_实现 11_队列类_顺序存储设计与实现 c++基础串讲复习1 c++基础串讲复习2 c++基础串讲复习3 c++基础串讲复习4 c++基础串讲复习5 代码 数据结构书籍和工具收集 文档 第四部分 C和C++与数据结构基础 01_数据结构课程_学习思路_学习基础 02_数据结构概念_基本概念 03_数据结构概念_逻辑关系_物理结构 04_算法基本概念和大O表示 05_算法的时间复杂度 06_算法的空间复杂度_空间换时间案例 07_课堂答疑_学员思路 08_线性表的理论知识梳理_重点在链表算法和具体数据类型的分离 09_线性表顺序存储设计和实现_环境搭建 10_线性表顺序存储设计和实现_api函数实现1 11_线性表顺序存储设计和实现_api函数实现2_插入算法 12_线性表顺序存储设计和实现_api函数实现3_get和delete 13_线性表顺序存储设计和实现_总结 14_线性表链式存储_设计与实现_框架搭建和链表技术领域推演_传智扫地僧 15_线性表链式存储_设计与实现_api实现_传智扫地僧 16_线性表链式存储_设计与实现_api实现下_传智扫地僧 17_线性表链式存储_总结 18_c++模板链表_类设计和测试框架搭建 19_c++模板链表_类实现 代码 文档 01_数据结构day01_知识点梳理 02_c++链表模板类_思想加强 03_循环链表api熟悉 04_循环链表应用_约瑟夫问题求解 05_循环链表_插入算法分析_传智扫地僧 06_循环链表_删除算法分析 07_循环链表_游标课堂答疑 08_循环链表_api串讲 09_循环链表_api熟悉 10_栈的顺序存储_设计与实现_测试框架搭建 11_中午课程回顾 12_栈模型和链表模型_顺序存储_思想分析_传智扫地僧 13_栈的顺序存储_设计与实现_api实现和调试 14_栈的顺序存储_设计与实现_课堂答疑 15_栈链式存储_设计与实现_测试框架搭建 16_栈链式存储_设计与实现_栈结点转换成链表结点_思想分析_传智扫地僧 17_栈链式存储_设计与实现_api实现_传智扫地僧 18_栈链式存储_设计与实现_内存管理 19_栈的应用案例_就近匹配 20_栈的应用案例_中缀转后缀 21_栈的应用案例_基于后缀表达式的计算_传智扫地僧 22_栈的应用案例_程序讲解 23_树模型抛砖 代码 文档 01_上一次课程_知识点回顾 02_队列顺序存储_设计与实现_测试框架 03_队列顺序存储_设计与实现_api函数的实现 04_队列链式存储_设计与实现_测试框架 05_队列链式存储_设计与实现_api函数实现 06_树的概念_定义_表示法_二叉树转换_树的存储 07_二叉树的概念_定义和性质 08_二叉树的概念_表示法_二叉树遍历 09_中午课程回顾 10_二叉树编程_遍历本质剖析和递归方式遍历_传智扫地僧 11_二叉树编程案例1_求叶子结点的数目 12_二叉树编程案例2和3_求树高度_拷贝二叉树 13_二叉树编程案例_课堂答疑 14_树非递归中序遍历_思想分析 15_树非递归中序遍历_遍历过程演示 16_树非递归中序遍历_实现(stl方式)_传智扫地僧 17_stl栈模型组合容器类对象_思想抛砖 18_创建树思想抛砖 代码 文档 01_上一次课程回顾 02_创建树_先序和中序确定树 03_学习数据结构_常用工具介绍 04_创建树_#号法 05_创建树_#号法编程实践 06_创建树_#号法课堂答疑 07_线索化_概念_过程分析 08_线索化_两个赋值指针变量线索化思想 09_线索化_线索化初始化流程 10_线索化_遍历思想 11_线索化_遍历树时,把结点插入链表中 12_中午课程总结和线索化逆序访问 13_霍夫曼树概念 14_排序_概念 15_排序_选择法 16_排序_插入法 17_排序_冒泡 18_排序_希尔排序 19_排序_希尔排序_分组很重要 20_排序_快速排序 21_排序_归并 22_数据结构课程_知识体系梳理 代码 文档 01_上一次课程知识点回顾 02_递归需要需要掌握的点补充 03_链表类_链式存储_测试 04_链表类_链式存储_api实现 05_链表类_链式存储_课堂答疑 06_栈类_链式存储_api实现 07_队列类_链式存储设计与实现_api 08_链表类_顺序存储_类设计和测试框架 09_链表类_顺序存储_类api实现 10_栈类_顺序存储_实现 11_队列类_顺序存储设计与实现 c++基础串讲复习1 c++基础串讲复习2 c++基础串讲复习3 c++基础串讲复习4 c++基础串讲复习5 代码 数据结构书籍和工具收集 文档 第5部分 C_C++与设计模式基础 01_设计模式课程安排和要求 02_UML的建模和基本概念 03_UML图_用例图_基础 04_UML图_用例图_人事管理系统案例_传智扫地僧 05_UML图_类图_基础和类关系依赖 06_UML图_类图_关联_聚合_组合_传智扫地僧 07_UML图_时序图_传智扫地僧 08_UML图_活动图_传智扫地僧 09_UML图_状态图_进程状态案例 10_UML图_协作图_包图_部署图 11_设计模式_概念和设计原则 12_中午课程回顾 13_设计模式基本原则_依赖倒转 14_设计模式基本_依赖倒置和迪米特法则 15_单例模式_懒汉式和饿汉式 16_懒汉式遇上多线程问题 17_懒汉式多线程同步优化 18_简单工厂模式 19_工厂模式_传智扫地僧 文档 源码 01_上一次课程知识点梳理 02_抽象工厂模式 03_抽象工厂课堂答疑 04_建造者模式_理论模型 05_建造者模式_实现 06_建造者模式_问题抛出 07_原型模式 08_建造模式总结 09_课堂交流从建造者模式说开去 10_厚积薄发话题 11_代理模式_传智扫地僧 12_装饰模式_传智扫地僧 13_中午课程回顾 14_适配器模式 15_桥接模式_理论模型 16_桥接模式_实现_传智扫地僧 17_组合模式_上 18_组合模式_下 19_外观模式 20_享元模式 文档 源码 01_设计模式知识体系梳理01 02_模板模式_传智扫地僧 03_命令模式_技术推演上 04_命令模式_技术推演下_传智扫地僧 05_责任链模式 06_策略模式_及题外话 07_策略模式_实现 08_中介者模式_问题抛出上 09_中介者模式_实现下 10_中午知识点回顾 11_观察者模式_传智扫地僧 12_备忘录模式 13_访问者模式_概念基本原理_案例了解 14_访问者模式_实现_传智扫地僧 15_状态模式_原理及代码串讲 16_解释器模式 17_迭代器模式_思想_传智扫地僧 18_迭代器模式_实现_传智扫地僧 19_设计模式知识体系梳理02 文档 源码
【原书名】 C++ Primer (4th Edition) 【原出版社】 Addison Wesley/Pearson 【作者】 (美)Stanley B.Lippman,Josée LaJoie,Barbara E.Moo 【译者】 李师贤 蒋爱军 梅晓勇 林瑛 【丛书名】 图灵计算机科学丛书 【出版社】 人民邮电出版社 【书号】 7-115-14554-7 【开本】 16开 【页码】 900 【出版日期】 2006-3-1 【版次】 4-1 【内容简介】 本书是久负盛名的C++经典教程,其内容是C++大师Stanley B. Lippman丰富的实践经验和C++标准委员会原负责人Josée Lajoie对C++标准深入理解的完美结合,已经帮助全球无数程序员学会了C++。本版对前一版进行了彻底的修订,内容经过了重新组织,更加入了C++ 先驱Barbara E. Moo在C++教学方面的真知灼见。既显著改善了可读性,又充分体现了C++语言的最新进展和当前的业界最佳实践。书中不但新增大量教学辅助内容,用于强调重要的知识点,提醒常见的错误,推荐优秀的编程实践,给出使用提示,还包含大量来自实战的示例和习题。对C++基本概念和技术全面而且权威的阐述,对现代C++编程风格的强调,使本书成为C++初学者的最佳指南;对于中高级程序员,本书也是不可或缺的参考书。本书的前言阐述了 第4版和前一版的不同之处。 【目录信息】 第1章 快速入门 1 1.1 编写简单的C++程序 2 1.2 初窥输入/输出 5 1.2.1 标准输入与输出对象 5 1.2.2 一个使用IO库的程序 5 1.3 关于注释 8 1.4 控制结构 10 1.4.1 while语句 10 1.4.2 for语句 12 1.4.3 if语句 14 1.4.4 读入未知数目的输入 15 1.5 类的简介 17 1.5.1 Sales_item类 17 1.5.2 初窥成员函数 19 1.6 C++程序 21 小结 22 术语 22 第一部分 基本语言 第2章 变量和基本类型 29 2.1 基本内置类型 30 2.1.1 整型 30 2.1.2 浮点型 32 2.2 字面值常量 34 2.3 变量 38 2.3.1 什么是变量 39 2.3.2 变量名 40 2.3.3 定义对象 42 2.3.4 变量初始化规则 44 2.3.5 声明和定义 45 2.3.6 名字的作用域 46 2.3.7 在变量使用处定义变量 48 2.4 const限定符 49 2.5 引用 50 2.6 typedef名字 53 2.7 枚举 53 2.8 类类型 54 2.9 编写自己的头文件 57 2.9.1 设计自己的头文件 58 2.9.2 预处理器的简单介绍 60 小结 62 术语 62 第3章 标准库类型 67 3.1 命名空间的using声明 68 3.2 标准库string类型 70 3.2.1 string对象的定义和初始化 70 3.2.2 String对象的读写 71 3.2.3 string对象的操作 72 3.2.4 string对象中字符的处理 76 3.3 标准库vector类型 78 3.3.1 vector对象的定义和初始化 79 3.3.2 vector对象的操作 81 3.4 迭代器简介 83 3.5 标准库bitset类型 88 3.5.1 bitset对象的定义和初始化 88 3.5.2 bitset对象上的操作 90 小结 92 术语 92 第4章 数组和指针 95 4.1 数组 96 4.1.1 数组的定义和初始化 96 4.1.2 数组操作 99 4.2 指针的引入 100 4.2.1 什么是指针 100 4.2.2 指针的定义和初始化 101 4.2.3 指针操作 104 4.2.4 使用指针访问数组元素 106 4.2.5 指针和const限定符 110 4.3 C风格字符串 113 4.3.1 创建动态数组 117 4.3.2 新旧代码的兼容 120 4.4 多维数组 122 小结 124 术语 125 第5章 表达式 127 5.1 算术操作符 129 5.2 关系操作符和逻辑操作符 131 5.3 位操作符 134 5.3.1 bitset对象或整型值的使用 135 5.3.2 将移位操作符用于IO 137 5.4 赋值操作符 137 5.4.1 赋值操作的右结合性 138 5.4.2 赋值操作具有低优先级 138 5.4.3 复合赋值操作符 139 5.5 自增和自减操作符 140 5.6 箭头操作符 142 5.7 条件操作符 143 5.8 sizeof操作符 144 5.9 逗号操作符 145 5.10 复合表达式的求值 145 5.10.1 优先级 145 5.10.2 结合性 146 5.10.3 求值顺序 148 5.11 new和delete表达式 150 5.12 类型转换 154 5.12.1 何时发生隐式类型转换 154 5.12.2 算术转换 155 5.12.3 其他隐式转换 156 5.12.4 显式转换 158 5.12.5 何时需要强制类型转换 158 5.12.6 命名的强制类型转换 158 5.12.7 旧式强制类型转换 160 小结 161 术语 162 第6章 语句 165 6.1 简单语句 166 6.2 声明语句 167 6.3 复合语句(块) 167 6.4 语句作用域 168 6.5 if语句 169 6.6 switch语句 172 6.6.1 使用switch 173 6.6.2 switch中的控制流 173 6.6.3 default标号 175 6.6.4 switch表达式与case标号 176 6.6.5 switch内部的变量定义 176 6.7 while语句 177 6.8 for循环语句 179 6.8.1 省略for语句头的某些部分 180 6.8.2 for语句头中的多个定义 181 6.9 do while语句 182 6.10 break语句 183 6.11 continue语句 184 6.12 goto语句 185 6.13 try块和异常处理 186 6.13.1 throw表达式 186 6.13.2 try块 187 6.13.3 标准异常 189 6.14 使用预处理器进行调试 190 小结 192 术语 192 第7章 函数 195 7.1 函数的定义 196 7.1.1 函数返回类型 197 7.1.2 函数形参表 198 7.2 参数传递 199 7.2.1 非引用形参 199 7.2.2 引用形参 201 7.2.3 vector和其他容器类型的形参 206 7.2.4 数组形参 206 7.2.5 传递给函数的数组的处理 209 7.2.6 main:处理命令行选项 210 7.2.7 含有可变形参的函数 211 7.3 return语句 211 7.3.1 没有返回值的函数 212 7.3.2 具有返回值的函数 212 7.3.3 递归 216 7.4 函数声明 217 7.5 局部对象 220 7.5.1 自动对象 220 7.5.2 静态局部对象 220 7.6 内联函数 221 7.7 类的成员函数 222 7.7.1 定义成员函数的函数体 223 7.7.2 在类外定义成员函数 225 7.7.3 编写Sales_item类的构造 函数 225 7.7.4 类代码文件的组织 227 7.8 重载函数 228 7.8.1 重载与作用域 230 7.8.2 函数匹配与实参转换 231 7.8.3 重载确定的三个步骤 232 7.8.4 实参类型转换 234 7.9 指向函数的指针 237 小结 239 术语 240 第8章 标准IO库 243 8.1 面向对象的标准库 244 8.2 条件状态 247 8.3 输出缓冲区的管理 249 8.4 文件的输入和输出 251 8.4.1 文件流对象的使用 251 8.4.2 文件模式 254 8.4.3 一个打开并检查输入文件的 程序 256 8.5 字符串流 257 小结 259 术语 259 第二部分 容器和算法 第9章 顺序容器 263 9.1 顺序容器的定义 264 9.1.1 容器元素的初始化 265 9.1.2 容器内元素的类型约束 267 9.2 迭代器和迭代器范围 268 9.2.1 迭代器范围 270 9.2.2 使迭代器失效的容器操作 271 9.3 顺序容器的操作 272 9.3.1 容器定义的类型别名 272 9.3.2 begin和end成员 273 9.3.3 在顺序容器中添加元素 273 9.3.4 关系操作符 277 9.3.5 容器大小的操作 278 9.3.6 访问元素 279 9.3.7 删除元素 280 9.3.8 赋值与swap 282 9.4 vector容器的自增长 284 9.5 容器的选用 287 9.6 再谈string类型 289 9.6.1 构造string对象的其他方法 290 9.6.2 修改string对象的其他方法 292 9.6.3 只适用于string类型的操作 293 9.6.4 string类型的查找操作 295 9.6.5 string对象的比较 298 9.7 容器适配器 300 9.7.1 栈适配器 301 9.7.2 队列和优先级队列 302 小结 303 术语 303 第10章 关联容器 305 10.1 引言:pair类型 306 10.2 关联容器 308 10.3 map类型 309 10.3.1 map对象的定义 309 10.3.2 map定义的类型 310 10.3.3 给map添加元素 311 10.3.4 使用下标访问map对象 311 10.3.5 map::insert的使用 313 10.3.6 查找并读取map中的元素 315 10.3.7 从map对象中删除元素 316 10.3.8 map对象的迭代遍历 316 10.3.9 “单词转换”map对象 317 10.4 set类型 319 10.4.1 set容器的定义和使用 319 10.4.2 创建“单词排除”集 321 10.5 multimap和multiset类型 322 10.5.1 元素的添加和删除 322 10.5.2 在multimap和multiset 中查找元素 323 10.6 容器的综合应用:文本查询程序 325 10.6.1 查询程序的设计 326 10.6.2 TextQuery类 327 10.6.3 TextQuery类的使用 328 10.6.4 编写成员函数 330 小结 332 术语 332 第11章 泛型算法 335 11.1 概述 336 11.2 初窥算法 339 11.2.1 只读算法 339 11.2.2 写容器元素的算法 341 11.2.3 对容器元素重新排序的算法 343 11.3 再谈迭代器 347 11.3.1 插入迭代器 348 11.3.2 iostream迭代器 349 11.3.3 反向迭代器 353 11.3.4 const迭代器 355 11.3.5 五种迭代器 356 11.4 泛型算法的结构 358 11.4.1 算法的形参模式 359 11.4.2 算法的命名规范 359 11.5 容器特有的算法 361 小结 362 术语 363 第三部分 类和数据抽象 第12章 类 367 12.1 类的定义和声明 368 12.1.1 类定义:扼要重述 368 12.1.2 数据抽象和封装 369 12.1.3 关于类定义的更多内容 372 12.1.4 类声明与类定义 374 12.1.5 类对象 375 12.2 隐含的this指针 376 12.3 类作用域 380 类作用域中的名字查找 382 12.4 构造函数 385 12.4.1 构造函数初始化式 387 12.4.2 默认实参与构造函数 391 12.4.3 默认构造函数 392 12.4.4 隐式类类型转换 393 12.4.5 类成员的显式初始化 396 12.5 友元 396 12.6 static类成员 398 12.6.1 static成员函数 400 12.6.2 static数据成员 400 小结 403 术语 403 第13章 复制控制 405 13.1 复制构造函数 406 13.1.1 合成的复制构造函数 409 13.1.2 定义自己的复制构造函数 409 13.1.3 禁止复制 410 13.2 赋值操作符 411 13.3 析构函数 412 13.4 消息处理示例 415 13.5 管理指针成员 419 13.5.1 定义智能指针类 421 13.5.2 定义值型类 425 小结 427 术语 427 第14章 重载操作符与转换 429 14.1 重载操作符的定义 430 14.2 输入和输出操作符 435 14.2.1 输出操作符<>的重载 437 14.3 算术操作符和关系操作符 439 14.3.1 相等操作符 440 14.3.2 关系操作符 441 14.4 赋值操作符 441 14.5 下标操作符 442 14.6 成员访问操作符 443 14.7 自增操作符和自减操作符 446 14.8 调用操作符和函数对象 449 14.8.1 将函数对象用于标准库算法 450 14.8.2 标准库定义的函数对象 451 14.8.3 函数对象的函数适配器 453 14.9 转换与类类型 454 14.9.1 转换为什么有用 454 14.9.2 转换操作符 455 14.9.3 实参匹配和转换 458 14.9.4 重载确定和类的实参 461 14.9.5 重载、转换和操作符 464 小结 466 术语 467 第四部分 面向对象编程与泛型编程 第15章 面向对象编程 471 15.1 面向对象编程:概述 472 15.2 定义基类和派生类 473 15.2.1 定义基类 474 15.2.2 protected成员 475 15.2.3 派生类 476 15.2.4 virtual与其他成员函数 479 15.2.5 公用、私有和受保护的继承 482 15.2.6 友元关系与继承 486 15.2.7 继承与静态成员 486 15.3 转换与继承 487 15.3.1 派生类到基类的转换 487 15.3.2 基类到派生类的转换 489 15.4 构造函数和复制控制 490 15.4.1 基类构造函数和复制控制 490 15.4.2 派生类构造函数 490 15.4.3 复制控制和继承 494 15.4.4 虚析构函数 495 15.4.5 构造函数和析构函数中的虚函数 497 15.5 继承情况下的类作用域 497 15.5.1 名字查找在编译时发生 498 15.5.2 名字冲突与继承 498 15.5.3 作用域与成员函数 499 15.5.4 虚函数与作用域 500 15.6 纯虚函数 502 15.7 容器与继承 503 15.8 句柄类与继承 504 15.8.1 指针型句柄 505 15.8.2 复制未知类型 507 15.8.3 句柄的使用 508 15.9 再谈文本查询示例 511 15.9.1 面向对象的解决方案 513 15.9.2 值型句柄 514 15.9.3 Query_base类 515 15.9.4 Query句柄类 516 15.9.5 派生类 518 15.9.6 eval函数 520 小结 522 术语 523 第16章 模板与泛型编程 525 16.1 模板定义 526 16.1.1 定义函数模板 526 16.1.2 定义类模板 528 16.1.3 模板形参 529 16.1.4 模板类型形参 531 16.1.5 非类型模板形参 533 16.1.6 编写泛型程序 534 16.2 实例化 535 16.2.1 模板实参推断 537 16.2.2 函数模板的显式实参 540 16.3 模板编译模型 542 16.4 类模板成员 545 16.4.1 类模板成员函数 548 16.4.2 非类型形参的模板实参 551 16.4.3 类模板中的友元声明 552 16.4.4 Queue和QueueItem的友元 声明 554 16.4.5 成员模板 556 16.4.6 完整的Queue类 558 16.4.7 类模板的static成员 559 16.5 一个泛型句柄类 560 16.5.1 定义句柄类 561 16.5.2 使用句柄 562 16.6 模板特化 564 16.6.1 函数模板的特化 565 16.6.2 类模板的特化 567 16.6.3 特化成员而不特化类 569 16.6.4 类模板的部分特化 570 16.7 重载与函数模板 570 小结 573 术语 574 第五部分 高级主题 第17章 用于大型程序的工具 579 17.1 异常处理 580 17.1.1 抛出类类型的异常 581 17.1.2 栈展开 582 17.1.3 捕获异常 583 17.1.4 重新抛出 585 17.1.5 捕获所有异常的处理代码 586 17.1.6 函数测试块与构造函数 586 17.1.7 异常类层次 587 17.1.8 自动资源释放 589 17.1.9 auto_ptr类 591 17.1.10 异常说明 595 17.1.11 函数指针的异常说明 598 17.2 命名空间 599 17.2.1 命名空间的定义 599 17.2.2 嵌套命名空间 603 17.2.3 未命名的命名空间 604 17.2.4 命名空间成员的使用 606 17.2.5 类、命名空间和作用域 609 17.2.6 重载与命名空间 612 17.2.7 命名空间与模板 614 17.3 多重继承与虚继承 614 17.3.1 多重继承 615 17.3.2 转换与多个基类 617 17.3.3 多重继承派生类的复制控制 619 17.3.4 多重继承下的类作用域 620 17.3.5 虚继承 622 17.3.6 虚基类的声明 624 17.3.7 特殊的初始化语义 625 小结 628 术语 628 第18章 特殊工具与技术 631 18.1 优化内存分配 632 18.1.1 C++中的内存分配 632 18.1.2 allocator类 633 18.1.3 operator new函数和 operator delete函数 636 18.1.4 定位new表达式 638 18.1.5 显式析构函数的调用 639 18.1.6 类特定的new和delete 639 18.1.7 一个内存分配器基类 641 18.2 运行时类型识别 646 18.2.1 dynamic_cast操作符 647 18.2.2 typeid操作符 649 18.2.3 RTTI的使用 650 18.2.4 type_info类 652 18.3 类成员的指针 653 18.3.1 声明成员指针 653 18.3.2 使用类成员的指针 655 18.4 嵌套类 658 18.4.1 嵌套类的实现 658 18.4.2 嵌套类作用域中的名字查找 661 18.5 联合:节省空间的类 662 18.6 局部类 665 18.7 固有的不可移植的特征 666 18.7.1 位域 666 18.7.2 volatile限定符 668 18.7.3 链接指示:extern "C" 669 小结 672 术语 673 附录 标准库 675 索引 703

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值