欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c++primer plus阅读笔记(八)

程序员文章站 2023-12-22 23:05:34
...

友元类

1.友元类的声明
class Tv{
    friend class Remote;//友元类就代表这肯定是一个类,无须前向声明Remote。
};

class Remote{
    ...
};

2.友元成员函数
不想使用友类所有函数都变成友元,可以使用友元成员函数。
!!编译器本身的符号解析和编译时按顺序来的,导致友元成员写起来要注意顺序。
class a ;       //a要前向声明,否则b中不知道是什么
class b {
public:
    void fn(a& temp);   //b中使用类型为a的对象temp
};

class a {
private:
    int num;            //声明a中的数据num
public:
    friend void b::fn(a& temp);//声明b中的函数为友元

};

inline void b::fn(a& temp) {    //此刻才有num的定义,才能补全该函数
    cout << temp.num << endl;
}

嵌套类

如果嵌套类是在另一个类的私有部分声明的,则只有后者能够使用它,如下。
class a{
private:
    class b{

    };
public:
    b temp;
};

其余的保护还有公共属性方面,和基本的数据成员的访问权限是一样的。

异常abort

#include<iostram>
#include<cstdlib>       //异常的头文件
using namespace std;

int main(){
    double a,b;
    scanf("%lf%lf",&a,&b);
    if(a==-b){
        cout<<"exception\n";
        abort();//调用abort函数直接终止当前进程。
    }
    cout<<1.0/(a+b);

return 0;
}

try..catch

try{

    fn();
}
catch(const char *s){

}

void fn(){
    throw "a exception";
}

没有try处理的throw

如果引发了一场却没有try块匹配或没有匹配的处理程序的时候,默认情况下,程序最终将调用abort()函数。

多个catch块

除了字符串之外,throw可以返回一切类型,同时使用多个catch进行捕获进行对应的处理,没有匹配类型不会进行转换,会调用 abort()函数

class temp{
public:
    int num;
};



try{

    fn();
}
catch(const char *s){
....
}
catch(const temp& s){//s只是一个副本,因为原本在栈解退的时候析构了。继承异常的时候,此处使用引用,派生类要放在前面。
....
}
cathc(...){//使用省略号捕获一切异常

}


void fn(){
    throw temp();
}

栈解退

try {}捕获的异常不一定是在下一层函数,反是在这个过程中throw的异常都会被捕获到。 从引发异常的函数条到包含try块和处理程序的函数,涉及到栈解退。
栈解退:函数由于出现异常而终止。陈旭将释放栈中的内存,但不会在释放栈的第一个返回地址后就停止,而是继续释放栈,直到找到一个位于try块中过得返回地址。
!!栈解退会导致内存泄漏,如下程序
void fn(){
    int *ptr=new int[10];
    ...
    if(xxx)
        throw exception();
    ...
    delete []ar; //栈解退导致此句来不及执行。
}

!!避免方式,使用try..catch处理,
void fn(){
    int *ptr=new int[10];
    ...
    try{
        if(xxx)
            throw exception();
    }
    catch(exception& ex){
        delete []ar;
        throw;
    }   
    ...
    delete []ar; //栈解退导致此句来不及执行。
}

RTTI

RTTI(runtime type identification)运行时确定类型

RTTI函数值适用于包含虚函数的类

dynamic_cast转化

转化的类型如果是继承中的高层类(派生)转给底层类,是安全的,否则不安全,dynamic_cast在不安全转化的时候将会返回空指针。


class a{...
virtual void fn(){...}
...};
class b:public a{...};
class c:public c{...};

a* ao=dynamic_cast<a*>(new b); //ok
b* bo=dynamic_cast<a*>(new a); //null

//dynamic_cast对于引用,不安全的时候会出现异常
try{
    a& ao=dynamic_cast<a& > ao1;
}
catch (const exception& e){

}

typeid

返回的是一个type_info的对象的引用,type_info是一个记录了对象类型的结构,其中含有成员函数name()可以指出当前类的名字,并重载了 == 和 !=运算符

运算符返回一个指出对象的类型的值
a ao;
b bo;
type_id(ao) == type_id(bo); //0

cout<<type_info(ao).name()<<endl;//class a

上一篇:

下一篇: