第十五章 友元、异常

本文介绍了C++中的友元类和友元成员函数的概念,通过遥控器和电视机的例子展示了如何使用友元。同时,详细阐述了异常处理机制,包括引发异常、捕获异常和栈解退的过程。还提到了动态类型转换和异常类型为对象的情况。最后,讨论了使用`dynamic_cast`进行运行时类型检查的重要性。
摘要由CSDN通过智能技术生成

友元类

友元类即将类作为另一个类的友元。

例如遥控器可以改变电视机的状态,但又不是电视机的一部分,也不属于电视机,所以可以将遥控器作为电视机的友元。

友元类的声明:使用friend class Remote;可以位于公有,私有,保护都行

class Tv {
    public:
        friend class Remote;
        Tv();
        bool onoff();
}

class Remote {
    private:
        int mode;

    public:
        void set_chan(Tv & t, int c) {t.channel = c;}
}

友元成员函数

也可以只将Remote::set_chan()左右Tv的友元函数

class Tv {
    friend void Remote::set_chan(Tv & t, int c);
}

异常机制

异常处理由三部分组成:

        1 引发异常

        2 使用处理程序捕获异常

        3 使用 try 块

void exceptionfun(int a) {
        if(a == 0) {
            throw "throw exception a == 0";
            cout << "exceptionfun 1" << endl;
        }
        cout << "exceptionfun end" << endl;
}
void startExceptionText() {
    try {
        exceptionfun(0);
        cout << "startExceptionText 1" << endl;
    } catch ( const char * s) {
        cout << s << endl;
    }
    cout << "startExceptionText end" << endl;
}

关键字 throw 是抛出(引发)异常,是跳转,即命令程序跳转到另一条语句(跳转到对应的catch)。throw 随后的值(例如字符串或者对象)指出了异常的类型,将和catch后边括号的参数类型对应(有点像函数)。

catch 关键字表示捕获异常,catch(类型声明),指出随后的异常处理程序要处理的异常类型。

异常被引发时候,程序应跳转到对应类型的catch块执行,try后边的语句也不会执行。当异常与该处理程序匹配时,程序将执行catch括号中的代码块。

执行throw相当于执行return语句,因此将终止当前函数的执行。但throw不是将控制权返回给调用函数,而是导致程序沿函数的调用序列后退,直到找到包含try块的函数。

将对象作为异常类型

可以将对象作为异常类型,如下,携带更多的信息

void exceptionfun(int a) {
        if(a == 0) {
            string s = "throw exception!!";
            throw s;
            cout << "exceptionfun 1" << endl;
        }
        cout << "exceptionfun end" << endl;
}
void startExceptionText() {
    try {
        exceptionfun(0);
        cout << "startExceptionText 1" << endl;
    } catch ( const string& s) {
        cout << s << endl;
    }
    cout << "startExceptionText end" << endl;
}

栈解退

如果函数由于出现异常(而不是函数返回)而终止,则程序也将释放栈中的内存,但是不会在释放栈中的第一个返回地址后停止,而是继续释放栈,直到找到一个位于try块中的返回地址,随后,控制权将转到块尾的异常处理程序,而不是函数调用后面的第一条语句,

对于栈中的自动类对象,类的析构函数将被调用

 throw 语句将控制权向上返回到第一个包含能够捕获相应异常的try-catch组合。

引发异常时编译器总是创建一个临时的拷贝,即使异常规范和catch块中指定的是引用。

void exceptionfun(int a) {
        if(a == 0) {
            string s = "throw exception!!";
            throw s;
            cout << "exceptionfun 1" << endl;
        }
        cout << "exceptionfun end" << endl;
}
void startExceptionText() {
    try {
        exceptionfun(0);
        cout << "startExceptionText 1" << endl;
    } catch ( const string& s) { //传入的是副本
        cout << s << endl;
    }
    cout << "startExceptionText end" << endl;
}

可以使用省略号来捕获任何异常

tey{} catch(...) {}

RTTI:

如果指向的对象(*pt)的类型为Type,或者是从Type直接或者间接派生来的类型,则下边的表达式将指针pt转换为Type类型的指针:

dynamic_cast<Type *>(pt)

否则,结果为0,即空指针。

if(ps = dynamic_cast<Type *>(pt)) {

        ps->Say();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值