【 声明:版权所有,转载请标明出处,请勿用于商业用途。 联系信箱:[email protected]】
19.1 控制内存分配
1.
当我们使用一条new表达式时:
string *sp = new string("a value");
string *arr = new string[10]
实际执行了三步操作。第一部,new表达式调用一个名为operator new(或者operator new[])的标准库函数。该函数分配一块足够大的,原始的,未命名的内存空间以便存储特定类型的对象。第二步,编译器运行相应的构造函数以构造这些对象,并为其传入初始值。第三部,对象被分配了空间并构造完成,返回一个指向该对象的指针。
2.
当我们使用一条delete表达式删除一个动态分配内存的对象时:
delete sp;
delete [] arr;
实际执行了两步操作。第一步,对sp所指的对象或者arr所指的数组中的元素执行对应的析构函数。第二步,编译器调用名为operator delete(或者operator delete[])的标准库函数释放内存空间。
19.2 运行时类型识别
1.运行时类型识别的功能由两个运算符实现:
typeid运算符,用于返回表达式的类型
dynamic_cast运算符,用于将基类的指针或引用安全地转换成派生类的指针或引用
2.
dynamic_cast运算符的使用形式如下表示:
dynamic_cast
dynamic_cast
dynamic_cast
其中type必须是一个类类型,并且通常情况下该类型应该含有虚函数。在第一种形式中,e必须是一个有效的指针;在第二种形式中,e必须是一个左值;在第三种形式中,e不能是左值
e的类型必须符合以下三个条件中的任意一个:e类型是目标type的共有派生类,e的类型是目标type的共有类型或者e的类型就是目标type的类型。如果符合,则类型转换可以成功,否则,转换失败。如果一条dynamic_cast语句的转换目标是指针类型并且失败了,则结果为0。如果转换目标是引用类型并且失败了,则dynamic_cast运算符将抛出一个bad_cast异常。
3.
typeid表达式的形式是typeid(e),其中e可以是任意表达式或类型的名字。
19.3 枚举类型
1.
C++包含两种枚举:限定作用域的和不限定作用域的。
C++11新标准引入了限定作用域的枚举类型。定义限定作用域的枚举类型的一般形式是:首先是关键字enum class(或者等价地使用enmu struct),随后是枚举类型名字以及花括号括起来的以逗号分隔的枚举成员列表。
定义不限定作用域的枚举类型时圣诺掉关键字class,枚举类型的名字是可选的。
2.
在C++11新标准中,我们可以在enum的名字后加上冒号以及我们想在改enum中使用的类型。如果我们没有指定enum的潜在类型,则默认情况下限定作用域的enum成员类型是int。
19.4 类成员指针
1.成员指针是指可以指向类的非晶态成员的指针。一般情况下,指针指向一个对象,但是成员指针指示的是类的成员,而非类的对象。类的静态成员不属于任何对象,因此无需特殊的指向静态成员的指针,指向静态成员的指针域普通指针没有什么区别。
2.我们必须在*之前添加classname::以标识当前定义的指针可以指向classname的成员。
19.5 嵌套类
1.一个类可以定义在另一个类的内部,前者称为嵌套类或嵌套类型。
嵌套类是一个独立的类,与外层类基本没什么关系。特别是,外层类的对象和嵌套类的对象是相互独立的。在嵌套类的对象中不包含外层类定义的成员;类似的,在外层类的对象也不包含任何嵌套类定义的成员。
2.嵌套类在其外层类中定义了一个类型成员。和其他成员类似,该类型的访问权限由外层类决定。位于外层类public部分的嵌套类实际上定义了一种可以随处访问的类型;位于外层类protected部分的嵌套类定义的类型只能被外层类及其友元和派生类访问;位于外层类private部分的嵌套类定义的类型只能被外层类的成员和友元访问。
19.6 union:一种节省空间的类
1.联合(union)是一种特殊的类,一个union考验有多个数据成员,但是在任意时刻只有一个数据成员可以有值。当我们给union的某个成员赋值之后,该union的其他成员就变成未定义的状态了。分配给一个union对象的存储空间至少要能容纳它的最大数据成员。
2.union可以定义包括构造函数和析构函数在内的成员函数。但是由于union既不能继承自其他类,也不能作为基类使用,所以在union中不能含有虚函数。
19.7 局部类
1.类可以定义在某个函数的内部,我们称这样的类为局部类。局部类定义的类型只在定义它的作用域内可见。和嵌套类不同,局部类的成员受到严格限制。
19.8 固有的不可移植的特性
1.类可以将其(非静态)数据成员定义成位域,在一个位域中含有一定数量的二进制位。当一个程序需要向其他程序或硬件设备传递二进制数据时,通常会用到位域。
位域的类型必须是整型或枚举类型。因为带符号位域的行为是由具体实现确定的,所以在通常情况下我们使用无符号类型保存一个位域。位域的声明形式实在成员名字之后紧跟一个冒号以及一个常量表达式,该表达式用于指定成员所占的二进制位数。
2.取地址运算符(&)不能作用于位域,因此任何指针都无法指向类的位域。
3.当对象的值可能在程序的控制或检测之外改变时,应该将该对象声明为volatile。关键字volatile告诉编译器不应对这样的对象进行优化。
4.C++使用链接指示指出任意非C++函数所用的语言。
5.链接指示可以有两种形式:单个的或符合的。链接指示不能出现在类定义或函数定义的内部。同样的链接指示必须在函数的每个声明中都出现。