当前位置: 首页 > news >正文

做网站的法律/廊坊关键词优化平台

做网站的法律,廊坊关键词优化平台,怎样做公司官方网站,上海网站定制费用一,异常机制 1.1,异常机制的作用 C异常是对程序在运行过程中发生异常情况的一种响应,异常提供了将程序的控制权从程序的一部分传递到另一部分的响应。异常的抛出和处理主要使用了以下三个关键字: try、 throw 、 catch 。 try&am…

一,异常机制

1.1,异常机制的作用

C++异常是对程序在运行过程中发生异常情况的一种响应,异常提供了将程序的控制权从程序的一部分传递到另一部分的响应。异常的抛出和处理主要使用了以下三个关键字: try、 throw 、 catch 。

try:放在try块中的代码是可能发生异常的代码。
throw:这个关键字引发异常,紧随其后的值指出了异常的特征。throw语句实际上是跳转,即命令程序跳到另一语句。throw语句必须包含在try块中,也可以是被包含在外层函数的try块中。
catch:捕获异常,随后是位于括号中的类型声明,它指出了异常处理程序要响应的异常类型。try-catch语句形式如下:

ry{包含可能抛出异常的语句;
}
catch(类型名 [形参名]){  // 捕获特定类型的异常//异常处理程序
}
catch(...) {  // 三个点则表示捕获所有类型的异常//异常处理程序
}

1.2,使用异常机制处理异常

double fun(double x, double y){if(y == 0){throw y;  //除数为0,抛出异常}return x / y;
}int main()
{double res;try{res = fun(2, 0);} catch(double val){cout<<"除数为:"<<val<<endl;exit(1);}return 0;
}

1.3,使用自定义的对象作为异常类型

使用自定义的对象作为异常类型的优点:

  • 可以使用不同的异常类型来区分引发不同的异常。
  • 对象可以携带信息,程序员可以根据这些信息来确定引发异常的信息。
class bad_func{
private:int v1;
public:bad_func(int v1){this->v1 = v1;}void mesg(){cout<<"除数不能为:"<<v1<<endl;}
};double fun(double x, double y){if(y == 0){throw bad_func(0);  //除数为0,抛出异常}return x / y;
}int main()
{double res;try{res = fun(2, 0);} catch(bad_func &exp){exp.mesg();exit(1);}return 0;
}

1.4,栈解退

假设在try块没有直接调用引发异常的函数,而是调用了另外一个会引发异常的函数,则程序的流程将从引发异常的函数直接跳到包含try块和处理程序的函数,这涉及到栈解退。栈解退的过程如下:如果一个函数由于异常而终止,程序将进行出栈的操作,但是不会在回退到栈的第一个返回地址后停止,而是继续回退栈,直到找到一个位于try块中的返回地址。然后控制权交给块尾的处理程序,而不是函数调用后的第一条语句,这个过程称为栈解退。

void funcA();
void funcB();
void funcC();void funcA(){funcB();
}void funcB(){funcC();
}void funcC(){throw 0;  //抛出一个异常
}int main()
{double res;try{funcA();} catch(int val){exit(1);}return 0;
}

funcC()函数引发了一个异常,此时会回退到调用funcC()的funcB(),在funcB()中发现funcC()并没有放到try块中,即在funcB()中没有对异常进行处理;此时会回退到调用funcB()的funcA(),同样在funcA()中发现funcB()并没有放到try块中,此时会回退到调用funcA()的main()函数,在main()函数中funcA()是放在try块中,此时程序的控制权就跳转到main()函数中。

1.5,throw-catch语句与函数参数与函数返回机制的区别

  • 函数func()中的返回语句将控制权返回到调用func()的函数,但是throw语句将控制权向上返回到第一个这样的函数,即包含能够捕获异常的try-catch块。
  • 引发异常时编译器总是创建异常对象的一个临时拷贝,即catch块中的参数是引用类型。
class bad_func{
private:int v1;
public:bad_func(int v1){this->v1 = v1;cout<<"bad_func构造函数"<<endl;}void mesg(){cout<<"除数不能为:"<<v1<<endl;}bad_func(const bad_func &p){this->v1 = p.v1;cout<<"bad_func复制构造函数"<<endl;}~bad_func(){cout<<"bad_func析构函数: "<<this<<endl;}
};double fun(double x, double y){if(y == 0){bad_func obj(0);cout<<"bad_func对象地址: "<<&obj<<endl;throw obj;  //除数为0,抛出异常}return x / y;
}int main()
{double res;try{fun(2, 0);} catch(bad_func &p){cout<<"bad_func对象地址: "<<&p<<endl;exit(1);}return 0;
}

输出结果

bad_func构造函数
bad_func对象地址: 0x69fe6c
bad_func复制构造函数
bad_func析构函数: 0x69fe6c
bad_func对象地址: 0x6f0dc0
bad_func析构函数: 0x6f0dc0Process returned 1 (0x1)   execution time : 0.008 s
Press any key to continue.

1.6,exception类

较新的C++编译器将异常合并到语音中。例如,为了支持该语言,exception头文件定义了exception类作为基类。其中有一个名为what()的虚函数,它返回一个字符串,该字符串的特征随实现而异。

class bad_func : exception{
private:int v1;
public:bad_func(int v1){this->v1 = v1;cout<<"bad_func构造函数"<<endl;}bad_func(const bad_func &p){this->v1 = p.v1;cout<<"bad_func复制构造函数"<<endl;}//重写虚函数what()const char* what(){cout<<"除数不能为0.";}
};double fun(double x, double y){if(y == 0){bad_func obj(0);cout<<"bad_func对象地址: "<<&obj<<endl;throw obj;  //除数为0,抛出异常}return x / y;
}int main()
{double res;try{fun(2, 0);} catch(bad_func &p){cout<<"bad_func对象地址: "<<&p<<endl;p.what();exit(1);}return 0;
}

二,RTTI

2.1,RTTI的作用

假设有一个类层次结构,其中的类都是从同一个基类派生而来的,则可以让基类指针指向其中任何一个类的对象。这样便可以调用这样一个函数:在处理一些信息后,选择一个类,并创建这种类型的对象,然后返回它的地址,而该地址可以被赋为基类指针。如何知道指针指向的是哪种类型的对象呢?在回答这个问题之前,先考虑为何要知道类型。可能希望调用类方法的正确版本,在这种情况下,这要该函数是类层次结构中所有成员都拥有的虚函数,则并不真正需要知道对象的类型。但派生类可能包含不是派生而来的方法,在这种情况下,只有某些类型的对象可以使用该方法。对于这种情况,RTTI提供了解决方案。

注意:

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

2.2,RTTI的工作原理

C++ 有三个支持RTTI的元素

2.2.1,dynamic_cast

dynamic_cast的语法与作用

dynamic_cast运算符将使用一个指向基类的指针来生成一个指向派生类的指针,用来执行”安全向下类型转换”,也就是用来决定某对象是否属于某继承体系中的某个类。通常,想知道类型的原因在于:知道类型后,就可以知道调用特定的方法是否安全。例如,有下面的类继承体系:

class Grand{...};
class Superb : public Grand{...};
class Magnificent : public Superb{...};

该运算符的用法如下,其中pg指向某个对象:

Superb *pb = dynamic_cast<Superb *>(pg);

这提出了这样的问题:指针pg的类型是否可以安全地转换为Superb *?如果可以,运算符将返回对象的地址,否则返回一个空指针。通常,如果指向的对象(*pt)的类型为Type或者是从Type直接或间接派生而来的类型,则下面的表达式将指针(*pt)转换为Type类型的指针。

dynamic_cast<Type *>(pt);

使用dynamic_cast来检查是否可以进行安全类型转换

class Grand{
public:virtual void speak(){cout<<"Grand Speak"<<endl;}
};class Superb : public Grand{
public:virtual void speak(){cout<<"Superb Speak"<<endl;}virtual void say(){cout<<"Superb say"<<endl;}
};class Magnificent : public Superb{
public:void speak(){cout<<"Magnificent Speak"<<endl;}void say(){cout<<"Magnificent say"<<endl;}
};

上面定义了三个类,Grand、Superb、Magnificent。Grand类定义了虚函数speak(),而其它的类都继承了该虚函数。Superb类定义了一个虚函数say(),而Magnificent也重新定义了它。程序定义了getOne()函数,该函数随机创建这三种类中某个类的对象。然后将对象的地址作为Grand*指针返回,循环将返回的指针赋给Grand*变量pg,然后使用pg调用speak()函数。因为这个函数是虚函数,所以代码能够正确调用指向的对象的speak()版本。如下:

Grand *pg;
for(int i = 0; i < 5; i ++){pg = getOne();pg->speak();
}

但是不能用相同的方式来调用say()函数,因为Grand类没有定义say()函数。然而,可以使用dynamic_cast运算符来检测是否可以安全地将pg转换为Superb类型指针。如果pg指向的对象的实际类型为Superb或Magnificent,则可以安全类型转换。在这两种情况下,都可以安全调用say()函数。

Grand *pg;
Superb *ps;
for(int i = 0; i < 5; i ++){pg = getOne();if(ps = dynamic_cast<Superb *>(pg)){ps->say();}
}

2.2.2,typeid

typeid运算符的语法与作用

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

typeid运算符的使用

typeid(Magnificent) == typeid(*pg);

如果pg指向的是一个Magnificent对象,则上面表达式的结果为true,否则为false。如果pg是一个空指针,程序将引发bad_typeid异常。

2.2.3,type_info

type_info的语法与作用

type_info的实现随厂商而异,但包含一个name()成员,该函数返回一个随实现而异的字符串,通常是类的名称。

type_info的使用

cout<<typeid(*pg).name()<<endl;
http://www.lbrq.cn/news/1449559.html

相关文章:

  • 泉州网站建设公司首选/合肥网站关键词排名
  • 网站建设与服务技能实训心得体会/营业推广
  • 单纯做网站的公司/东莞百度快速排名
  • 网站网页/关于新品牌的营销策划
  • 金融网站素材/全国唯一一个没有疫情的城市
  • 专门做日本旅游的网站/成人短期就业培训班
  • 服装网站建设策划/域名注册商怎么查
  • 公司网站模块制作/网络推广优化seo
  • 宣武上海网站建设/有什么公司要做推广的
  • 什么网站算是h5做的/免费的网站软件下载
  • wordpress资讯站模板/搜索引擎推广简称
  • 网址自动生成手机网站/上海百度推广开户
  • 网站做sem优化/珠海网站设计
  • 网站推广的方法和手段/网络运营商
  • cms网站栏目介绍/近期出现的病毒叫什么
  • 莱芜警方网站官网/刷粉网站推广马上刷
  • 伪静态一个虚拟空间做两个网站/链接购买
  • 网页类型分类7种/seo和网络推广有什么区别
  • wordpress企业仿站/厦门seo外包服务
  • 湖南网站建设磐石网络口碑好/高端营销型网站
  • 广州网站建设乐云seo模板中心/如何在网上推广自己的产品
  • skech做网站交互流程/如何网上免费打广告
  • 租房网站开发视频教程/信息流优化师没经验可以做吗
  • 做鞋子皮革有什么网站/seo全称
  • wordpress f4v/重庆百度seo公司
  • 如何不用百度推广做网站/网络营销的8个基本职能
  • 温州营销网站制作费用/长沙网站公司品牌
  • 如何搞好网站建设/点石关键词排名优化软件
  • 最新seo黑帽技术工具软件/福建搜索引擎优化
  • diango做的网站怎么用/小米的推广软文
  • Rust进阶-part4-智能指针2
  • Springboot集成Log4j2+MDC串联单次请求的日志
  • 数据结构(14)链式结构二叉树
  • 【MySQL】MySQL中锁有哪些?
  • C++编译过程与GDB调试段错误和死锁问题
  • 回归的wry