文档章节

C++ Primer Plus(十五)——友元、异常和其它

吃一堑消化不良
 吃一堑消化不良
发布于 2017/03/26 11:11
字数 1639
阅读 32
收藏 0

1. 类声明的位置决定了类的作用域和可见性。类可见后,访问控制规则将决定程序对嵌套类成员的访问权限,包含嵌套类的类对于嵌套类并没有访问特权。

嵌套类、结构、枚举的作用域特征

声明位置 包含它的类是否可以使用它 从包含它的类派生而来的类是否可以使用它 在外部是否可以使用
私有部分
保护部分
公有部分 是,通过类限定符来使用

2. C++11抛弃了异常规范,它可能出现在函数原型和函数定义中,可包含类型列表,也可不包含,如:

double harm(double e) throw(bad_thing);
double marm(double) throw();

C++11支持一种特殊的异常规范,可使用新增的关键字noexcept指出函数不会引发异常。

3. 程序进行栈解退以回到能够捕获异常的地方时,将释放栈中的自动存储型变量。

4. 虽然throw-catch 机制类似于函数参数和函数返回机制,但还是有些不同之处。

(1)将函数控制权交到第一个包含能捕获相应异常的try-catch组合

(2)引发异常时总是创建一个临时拷贝,即使异常规范和catch块中指定的是引用。为何使用引用呢?不是已经生成副本了么?那是因为基类引用可以执行派生类对象,即在异常规范中只需列出一个基类引用,它将与任何派生类对象匹配。可以创建捕获对象而不是引用的处理程序。在catch语句中使用基类对象时,将捕获所有派生类对象,但派生特性将被剥去,因此将使用虚方法的基类版本。

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

5. C++异常:

对于使用new导致的内存分配问题,C++的处理方式是让new引发bad_alloc异常,它从exception派生而来。C++标准提供一种标记开关,其用法如下:

int *pi = new (std::nothrow) int; //失败返回空指针
int *pa = new (std::nowthrow) int[500]; //失败抛出异常

6. 未捕获异常不会导致程序立即终止,而是首先调用函数 terminate( )。在默认情况下,terminate将调用abort( )函数。可以调用set_terminate( )函数来指定terminate应调用的函数:

// 以下函数包含在 exception 中

typedef void (*terminate_handler)();
terminate_handler set_terminate(terminate_handler f) throw(); //c++98
terminate_handler set_terminate(terminate_handler f) noexcept(); //c++11

void terminate(); //c++98
void terminate() noexcept; //c++11

7. 意外异常,程序将调用unexpected( )函数,这个函数将调用terminate( ),后者在默认情况下将调用unexpected函数,若要修改unexpected行为,则可以使用set_unexpected( )函数:

// 以下函数包含在 exception 中

typedef void (*unexpected_handler)();
unexpected_handler set_terminate(unexpected_handler f) throw(); //c++98
unexpected_handler set_terminate(unexpected_handler f) noexcept(); //c++11

void unexpected(); //c++98
void unexpected() noexcept; //c++11

set_unexpected( )函数可以:

(1)通过调用terminate( )(默认行为)、abort( )或exit( )来终止程序

(2)引发异常,引发异常的结果取决于unexpected_handler函数所引发的异常以及引发异常的函数的异常规范:

        (1) 如果新引发的异常由原来的异常规范匹配,则程序从那里开始正常处理,即寻找和新引发异常匹配的catch块,这种方法将用预期的异常取代意外异常。

        (2) 如果新引发的异常与原来的异常规范不匹配,且异常规范中没有包括 std::bad_exception 类型,则程序将调用terminate( )。

        (3) 如果新引发的异常与原来的异常规范不匹配,且原来的异常规范包含了 std::bad_exception 类型,则不匹配的异常将被 std::bad_exception 异常取代。

8. RTTI(Runtime Type Identification)运行阶段类型识别,只适用于包含虚函数的类,原因在于只有对于这种类层次结构,才应该将派生类对象赋给基类指针。C++有三个支持RTTI的元素:

(1)dynamic_cast:它回答了“类型转换是否安全”的问题,并使用一个指向基类的指针来生成派生类的指针,否则,该运算符将返回0——空指针。也可以将dynamic_cast用于引用,其用法稍微有些不同:没有空指针对应的引用值,因此无法使用特殊的引用值来指示失败。当请求不正确时,dynamic_cast将引发bad_cast异常,这种异常是从exception类派生而来,它是在头文件typeinfo中定义的。

(2)type_id:它用来确定两个对象是否为同种类型,接受两种参数:类型、结果为对象的表达式,返回一个type_info对象,type_info类重载了 == 和 != 运算符,以便可以使用这些运算符进行类型比较。如果表达式是空指针,则程序将引发bad_typeid异常。type_info类的实现随厂商而异,但包含一个name( )成员,该函数返回一个随实现而异的字符串,通常是类的名称。

(3)type_info结构存储了相关特定类型的信息。

即使编译器支持RTTI,在默认情况下,它也有可能关闭这个特性。如果该特性被关闭,程序可能仍能通过编译,但将出现运行阶段错误,在这种情况下,应查看文档或菜单选项。

9. 类型转换运算符:
(1)dynamic_cast:用于将派生类指针转换为基类指针从而确保可以安全的调用虚函数,使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过

(2)const_cast:只能改变值的 const 或 volatile 属性,也就是说type_name和expression类型必须相同。const_cast不是万能的,它可以修改指向一个值的指针,但修改const值的结果是不确定的。

(3)static_cast:只有type_name可被隐式转换为expression所属类型或expression可被隐式转换为type_name属性类型时,这种转换才是合法的。

(4)reinterpret_cast:用来处理无关类型之间的转换,它会产生一个新的值,这个值会有与原始参数(expressoin)有完全相同的比特位。

© 著作权归作者所有

吃一堑消化不良
粉丝 28
博文 188
码字总数 112947
作品 0
浦东
程序员
私信 提问
《鸡啄米C++编程入门系列》系列技术文章整理收藏

《鸡啄米C++编程入门系列》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201812.html 文章 鸡啄米:C++编程入门系列之前言 鸡啄米:C++编程入门系列之一(进制...

开元中国2015
2015/06/27
0
0
11月推荐给程序员们的四本书

难得在家休息一段时间,职业病的原因吧,推荐技术书的习惯一时间没能改变。借着自己的微信平台,每天向大家推荐一些靠谱的内容,希望大家能喜欢。 先跟着我来看我今天推荐的第一本书吧! C+...

生气的散人
2013/11/11
960
2
关于派生类到基类的可访问性。。。

以下是C++ primer 4 上说的: 1.如果是 public 继承,则用户代码和后代类都可以使用派生类到基类的转换。 2.如果类是使用 private 或 protected 继承派生的,则用户代码不能将派生类型对象转...

反方向
2012/10/27
872
6
VS2010/MFC编程入门教程之目录和总结(鸡啄米)

鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够。以此教程的知识为基础,学习VS2010/MFC较为深入的内容已非难事...

weixin_40647819
2018/05/23
0
0
【jni 编程】—— NDK环境搭建

在《站在巨人的肩膀上,谈app的创新性》一文中 http://my.oschina.net/liusicong/blog/311971,我提到过构建app技术壁垒的必要性。在构建技术壁垒时,我们往往需要调用许多库函数,例如:图像...

刘小米
2014/09/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

mysql mysql中的视图

视图是由数据库中的一个表或者多个表导出的虚拟表,方便用户操作。其内容是由查询定义。 视图是存储在数据库中的查询的sql语句。 一、创建视图 1. 查看创建视图的权限 select Select_priv,C...

edison_kwok
13分钟前
0
0
以太坊中文文档翻译-账号

本文原文链接 点击这里获取Etherscan API 中文文档(完整版) 完整内容排版更好,推荐读者前往阅读。 账号(Account) 账号及地址相关的 API,接口的参数说明请参考Etherscan API 约定, 文档中...

Tiny熊
22分钟前
0
0
Springboot 集成redis

这里只做单机版简单集成,不过为项目中使用 1.在pom文件中引入支持 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redi......

贾峰uk
54分钟前
3
0
Qt编写安防视频监控系统4-删除视频

一、前言 一般会有两种处理方式来删除视频,一种是鼠标右键菜单,删除当前视频或者删除所有视频,一种是直接按住当前视频,移到视频通道界面以外就表示删除当前视频,这也是个比较人性化的设...

飞扬青云
58分钟前
2
0
NCRE考试感想 三级信息安全(下)

时代的变迁 一些学科的兴起,一些学科的没落;一些职业的兴起,一些职业的没落。在2016年,新闻报道中说:国务院取消了百余项职业资格证书。一切都处于变动之中,要找到变化的规律,跟上时代...

志成就
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部