《C++ Primer Plus》学习笔记9
第15章 友元、异常和其它
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
主要内容:
1)友元类
2)友元类方法
3)嵌套类
4)引发异常、try块和catch块
5)异常类
6)运行阶段类型识别(RTTI)
7)dynamic_cast和typeid
8)static_cast、const_cast和reiterpret_cast
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
1、对于Remote对象的TV方法,其原型可在Remote类声明之前声明,但必须在Remote类声明之后定义,以便编译器有足够的信息来编译该方法。
class Tv
{
friend class Remote;
public:
void buzz(Remote & r);
……
};
class Remote
{
friend class Tv:
public:
void Bool volup(Tv & t)
{
t.volup();
}
};
inline void Tv::buzz(Remote & r)
{
……
}
由于Remote的声明位于Tv声明的后面,所以可以在类声明中定义Remote::volup(),但是Tv::buzz方法必须在Tv声明的外部定义,使其位于Remote声明的后面。
共同的友元
需要使用友元的另一种情况是,函数需要访问两个类的私有数据,从逻辑上看,这样的函数应是每个类的成员函数,但这是不可能的,它可以是一个类的成员,同时是另一个类的友元,不过有时将函数作为两个类的友元更加合理。
补充:友元使得能够为类开发更灵活的接口
2、嵌套类
在C++中,可以将类声明放在另一个类中,在另一个类中声明的类被称为嵌套类(nested class),它通过提供新的类型类作用域来避免名称的混乱。
对类进行嵌套通常是为了帮助实现另一个类,避免名称冲突。
补充:嵌套类是在其他类中声明的类,它有助于设计这样的助手类,即实现其他类,但不必是公有接口的组成部分。
class Queue
{
//class scope definitions
//Node is a nested structure definition local to this class
struct Node
{
Item item;
struct Node * nest;
};
}
Node实际上是一个嵌套类。
1)嵌套类的作用域
如果嵌套类是私有部分声明的,则只有后者知道它。前面Node类就是这种情况,因为类的默认访问权限是私有的;对于包含它的类是可以使用它;从包含它的类派生而来的类不能使用,外部世界也不能使用它。
如果嵌套类是保护分声明的,则只有后者知道它。对于包含它的类是可以使用它;从包含它的类派生而来的类能使用,外部世界也不能使用它。
如果嵌套类是公部分声明的,对于包含它的类是可以使用它;从包含它的类派生而来的类能使用,外部世界也能使用它。
嵌套结构和枚举的作用域与这个相同。
3、异常
1)调用abort
处理方式,如果其中一个参数是另一个参数的负值,则调用abort()函数
其典型实现是向标准错误流发送消息abnormal program termination(程序异常终止)
2)返回错误码
一种比异常终止更加灵活的方法是使用函数的返回值来指出问题。
3)异常机制
对于异常处理有三个组成部分
①引发异常
throw语句实际上是跳转,关键字表示引发异常,紧跟其后的值指出了异常的特征
②捕获有处理程序的异常
catch关键字表示捕获异常
③使用try块
try块标识其中特定的异常可能被激活的代码块,它后面跟一个或多个catch块
补充:C++异常机制为处理拙劣的编程事件,如不适合的值,I/O失败等,提供了一种灵活的方式,引发异常将终止当前执行的函数,将控制权传给匹配的catch块。catch块紧跟在try块中的代码。
4、RTTI
RTTI是运行阶段类型识别
RTTI特性让程序能够检测对象的类型,dynamic_cast操作符用于将派生类指针转换为基类指针,其主要用途是确保可以安全的调用虚函数。
RTTI的工作原理:
C++有3个支持的RTTI的元素,
如果可能的话,dynamic_cast操作符将使用一个指向基类的指针来生成一个指向派生类的指针,否则,该操作符返回0——空指针。
typeid操作符返回一个指出对象的类型的值
type_info结构存储了有关特定类型的信息
RTTI只适用于包含虚函数的类。
通常,如果指向的对象(*pt)的类型是Type或者是从Type直接或间接派生而来的类型,则表达式:dynamic_cast<Type *>(pt)将指针pt转换为Type类型的指针;否则,结果为0.即空指针。