Chapter15 友元、异常和其他

Chapter15 友元、异常和其他

15.1 友元

类并非只能拥有友元函数,也可以将类作为友元。在这种情况下友元类的所有方法都可以访问原始类的私有成员和保护成员。

下述语句可以使类成为友元类:friend class className,友元声明可以位于公有、私有或保护部分,其所在的位置无关紧要。

内联函数的链接性时内部的,这意味着函数定义必须在使用函数的文件中。

15.2 嵌套类

在另一个类中声明的类被称为嵌套类(nexted class),它通过提供新的类型类作用域来避免名称混乱,包含类的成员函数可以创建和使用被嵌套类的对象。

对类进行嵌套与包含并不同。包含意味着将类对象作为另一个类的成员,而对类进行嵌套不创建类成员,而是定义了一种类型,该类型仅在包含嵌套类声明的类中有效。

如果嵌套类是在另一个类的私有部分声明的,则只有后者知道它;如果嵌套类实在另一个类的保护部分声明的,则它对于后者来说是可见的,但对于外部世界则是不可见的;如果嵌套类是在另一个类的共有部分声明的,则允许后者、后者的派生类以及外部世界使用它。
image-20201101154210427

对嵌套类访问权的控制规则与常规类相同。

15.3 异常

abort()函数的原型位于头文件cstdlib中,其典型实现是向标准错误流发送消息abnormal program termination,然后终止进程。abort()是否刷新问及那缓冲区取决于实现,而exit()函数刷新文件缓冲区,但不显示消息。

对异常的处理通常包括3个组成部分:

  • 引发异常
  • 使用处理程序捕获异常
  • 使用try块

throw语句实际上是跳转,即命令程序跳到另一条语句。throw关键字表示引发一场,紧随其后的值指出了异常的特征。

执行throw语句类似于执行返回语句,因为它也将终止函数的执行;但throw不是将控制权返回给调用程序,而是导致程序沿函数调用序列后退,直到找到包含try块的函数。

catch块类似于函数定义,但并不是函数定义,关键字catch表明这是一个处理程序,当异常与该处理程序匹配时,程序将执行其括号中的代码。

如果程序引发了异常,而没有try块或灭有匹配的处理程序时,在默认情况下,程序最终将调用abort()函数。

通常引发异常的函数将传递一个对象。这样做的重要优点之一是,可以使用不同的异常类型来区分不同的函数在不同情况下引发的异常。

如果有一个异常类继承层次结构,应该这样排列catch块:将捕获位于层次结构最下面的异常类的catch放在最前面,将捕获基类异常的catch语句放在最后面。

一般而言,logit_error系列异常表明存在可通过编程修复的问题,而runtime_error系列异常表明存在无法避免的问题。

15.4 RTTI

C++有3个支持RTTI(运行阶段类型识别,Runtime Type Identification)的元素:

  • 如果可能的话,dynamic_cast运算符将使用一个指向基类的指针来生成一个指向派生类的指针;否则该运算符返回0——空指针;
  • typeid运算符返回一个指出对象的类型的值;
  • type_info结构存储了有关特定类型的信息。

只能将RTTI用于包含虚函数的类层次结构中,原因在于只有对于这种类层次结构,才应该将派生对象的地址赋给基类指针。

通常,如果指向的对象(*pt)的类型为Type或是从Type直接或间接派生而来的类型,则下面的表达式将指针pt转换为Type类型的指针:dynamic_cast<Type *>(pt),否则,结果为0,即空指针。

typeid运算符使得能够确定两个对象是否为同种类型,它接受两种参数:类名、结果为对象的表达式。typeid运算符返回一个对type_info对象的引用。其中type_info是在头文件typeinfo中定义的一个类,它重载了==和!=运算符,以便可以使用这些运算符来对类型进行比较。

15.5 类型转换运算符

static_cast用于数据类型的强制转换,强制将一种数据类型转换为另一种数据类型。

reinterpret_cast主要有三种强制转换用途:改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型

const限定符通常被用来限定变量,用于表示该变量的值不能被修改。而const_cast则正是用于强制去掉这种不能被修改的常数特性,但需要特别注意的是const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用

在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全