C++primer(第五版)第十九章(特殊工具与技术)

本章(也是最后一章)介绍了C++一些非常特殊的性质,对于大多数程序员来说很少会用到本章的内容.所以我就简简单单地过一遍(因为我也看不太懂). 

19.1 控制内存分配

19.1.1 重载new和delete

当应用程序希望控制内存分配的过程时,可以使用 operator new (operator new[ ])可以对new进行重载,相同的 operator delete (operator delete[ ])可以对delete重载.当定义了全局的operator new ([ ])和operator delete ([ ])后,则必须保证这些函数是正确的,因为分配内存在整个程序中都是至关重要的.(个人认为没事别重载这些,咱的水平不够)

19.1.2 定位new表达式

C++早期版本没有allocate类,所以如果需要把内存分配和初始化分离开则需要调用operator new ([ ])和operator delete ([ ]),然后需要使用到定位new,但是因为现在标准库中有了allocate类,可以不用我们额外操作就可以达到目的,所以就不介绍定位new了.

19.2 运行时类型识别

运行时类型识别(run-time type identification,RTTI).

在使用RTTI时要非常小心(本章内容使用时都要非常小心),最好定义虚函数而不是直接接管类型管理的重任.

19.2.1 dynamic_cast运算符

该运算符使用形式如下:

dynamic_cast(e)    //e必须是有效指针
dynamic_cast(e)    //e必须是一个左值
dynamic_cast(e)   //e不能是左值 

上面的type必须是一个类类型,并且通常情况下应该含有虚函数.该运算符能将e转换成尖括号<>中的类型,成功则返回转换后的结果,指针转换失败则结果为0,引用转换失败则直接抛出异常.

对一个空指针执行dynamic_cast结果是type类型的空指针.

19.2.2 typeid运算符

该运算符使用形式如下:

typeid(e)    

操作结果为一个常量对象的引用,该常量对象是标准库类型的 type_info 或者 type_info 的公有派生类型. type_info 定义在 typeinfo头文件中.

通常情况会用typeif来判断两条表达式的类型是否相同.

当typeid作用于指针时,返回的结果是该指针的静态编译时类型,因此如果是空指针,则会抛出异常.

19.2.3 使用RTTI

 dynamic_cast转换类型,typeid判断类型,至于怎么使用就自由发挥啦.

19.2.4 type_info类

C++primer(第五版)第十九章(特殊工具与技术)_第1张图片

 19.3 枚举类型

枚举类型使我们可以将一组常量数据组织在一起,而不同的枚举类型又是一种新的类型(字面值常量类型).

C++包含限定作用域和不限定作用域的两种枚举类型.定义方式如下:

enum class 枚举类型的名字 { 成员1,成员2,成员3 };    //限定作用域
enum 枚举类型的名字 { 成员1,成员2,成员3 };          //不限定作用域

默认情况下枚举值从0开始,依次+1,例如上面的成员1的具体值为0,成员2为1.但我们也可以指定值,例如:

enum class 枚举类型的名字 { 成员1=100,成员2=200,成员3=200 };

并且同一个枚举类型里的枚举成员的枚举值可以不唯一.若没有显示指定初始值,则默认为前一个枚举成员的枚举值+1.

19.4 类成员指针

成员指针是指可以指向类的非静态成员的指针,并且成员指针指示的是类的成员而不是类的对象.

类的静态成员不属于任何对象,因此不用特殊的指向静态成员的指针.

19.4.1 数据成员指针

当我们初始化一个成员指针或给成员指针赋值时,该指针并没有指向任何数据,成员指针不是该成员所属的对象,只有当解引用成员指针时我们才提供对象的信息.

19.4.2 成员函数指针

可以创建指向成员函数的指针,不懂用什么类型来接就使用auto.

19.4.3 将成员函数用作可调用对象

和普通的函数指针不同,成员指针不是一个可调用对象,因此不支持函数调用运算符.

可以使用标准库模板 function 来获取可调用对象.

也可以使用标准库功能 men_fn 来让编译器负责推断成员的类型, men_fn 和 function 一样定义在 function头文件中,并且可以从成员指针生成一个可调用对象,和function不同的是men_fn可以根据成员指针的类型推断可调用对象的类型,无需用户显式指定.

另外用bind也可以从成员函数生成一个可调用对象.

19.5 嵌套类

一个定义在另一个类内部的类我们称之为嵌套类.

嵌套类是一个独立的类,嵌套类不能使用外层类定义的成员,外层类的对象也不包含嵌套类的成员.

若定义了外层的类而还没有定义嵌套类,则外层的类属于不完全类型.

19.6 union:一种节省空间的类

一个union(联合)类型可以有多个数据成员,但是在任意时刻只能有一个数据成员有值,当我们给union的某个成员赋值以后其他成员就变成了未定义状态.

union不能含有引用类型的成员,并且成员不能有虚函数,因为union不能继承也不能当基类.

C++11中可以为union指定访问限定符(public , private , protected),默认是public.

和enum一样,每定义一个union都是一种新类型.使用时如下:

union 联合类型的名字{
    int a;
    char b;
    string c;
}
联合类型的名字 a = { 10 };

从上面可以看出初始化一个联合可以使用花括号{},并且联合类型的成员类型不能重复,否则不知道赋值给哪个成员.

19.7 局部类

 定义在函数内部的类被称为局部类.

局部类的所有成员必须完整定义在类的内部,不能类外定义类成员.

局部类不能使用函数作用域中的变量.

19.8 固有的不可移植的特性

为了支持底层编程,C++定义了一些固有的不可移植的特性(指因机器而异的特性).

19.8.1 位域

位域在内层中的布局是与机器相关的.

可以将非静态数据成员定义成位域,在一个位域中含有一定数量的二进制位,当一个程序向其他程序或是硬件设备传递二进制数据时常常会用到位域,

位域的类型必须是整型或是枚举类型,通常使用无符号类型保存一个位域.位域的声明方式为在成员名字后紧跟冒号和一个常量表达式,常量表达式哟用于说明指定成员所占的二进制位数,例如:

class File{
    unsigned int a: 2;    //a占2位
    unsigned int b: 3;    //b占3位
}

使用时和使用类成员一样. 

19.8.2 volatile 限定符

volatile的确切含义与机器有关,需要阅读编译器文档.

用volatile修饰(与const修饰的位置相似)的变量不会被编译器优化.

19.8.3 链接指示:extern"C"

若要把C++代码和别的语言(包括C语言,因为C++就是一门独立的语言)放在一起使用,要求我们有有权访问其他语言的编译器,并且这个编译器要和C++编译器兼容.

链接指示可以有单个和复合两种形式,链接指示不能出现在类定义或者函数定义的内部,同样的链接指示必须在函数的每个声明中出现.

C++primer(第五版)第十九章(特殊工具与技术)_第2张图片

 链接指示对整个声明都有效.

你可能感兴趣的:(C++primer,c++,开发语言)