C++ 学习笔记(18)异常处理(noexcept说明符和noexcept运算符、构造函数的try和catch)、命名空间(using声明和using指示)、多继承(虚继承)
2018-02-23 01:12
821 查看
C++ 学习笔记(18)异常处理(noexcept说明符和noexcept运算符、构造函数的try和catch)、命名空间(using声明和using指示)、多继承(虚继承)
参考书籍:《C++ Primer 5th》C++ 学习笔记(5)语句、异常
18.1 异常处理
18.1.1 抛出异常
析构函数中,对于可能抛出异常的操作,必须放在try块中,并得到处理。否则在析构函数抛出异常时,程序会直接终止。异常对象:使用异常抛出表达式对异常对象进行拷贝初始化。
表达式如果是类类型,必须含有可访问的析构函数、可访问的拷贝或移动构造函数。
表达式是数组或函数类型,会被转换成对应的指针。
异常处理完毕后,异常对象会被销毁。
18.1.2 捕获异常
如果catch接受的异常与某个继承体系有关,则最好将catch的参数定义成引用类型。异常的类型和catch声明的类型是精确匹配的:
允许非常量转换成常量。
允许派生类转向基类。
数组和函数转换成对应指针。
其他都不能匹配(包括算术类型转换,类类型转换)。
重新抛出(rethtowing):catch语句中再抛出异常(直接一句
throw;,不含表达式)。用于将异常传递给另一个catch继续处理。
捕获所有异常:
catch(...),必须出现在所有catch组合之后。
18.1.3 函数try语句块与构造函数
要处理构造函数的初始值抛出的异常,将构造函数写出函数try语句块(函数测试块)的形式。A::A() try : value(123) { } catch ( const runtime_error &e) { } // 将 try 写在初始化列表之前,在函数体后添加catch语句块。
18.1.4 noexcept 异常说明
如果确认函数不会抛出异常,就可以执行某些特殊的优化操作。不知道如何处理异常时,也可以声明noexcept。
如果函数声明了不抛出异常,但还是抛出了,程序会调用terminate确保不在运行时抛出异常的承诺。
// noexcept 说明符 : 跟在函数列表之后 void func() noexcept; void func() throw(); // 等价上面 void a() noexcept(true); // a不会抛出异常 void b() noexcept(false); // b可能抛出异常 // ----- // noexcept 运算符: 与bool实参出现 bool bv = noexcept(a()); // 因为a不会抛出异常,所返回值为true noexcept(e); // 判断e对象的所有函数是不是都不抛出异常且不含有throw。
函数指针有noexcept说明符时,指向的函数也必须有。
虚函数有noexcept时,派生的虚函数也必须用。
18.1.5 异常类层次
运行时错误:程序运行时才能检测到。
逻辑错误:程序代码中的错误。
18.2 命名空间
18.2.1 命名空间定义
内联命名空间:可以直接被外层命名空间使用。关键字inline必须出现在命名空间第一次定义的地方。namespace AAA { namespace BBB { int i; } inline namespace CCC { int j; } } void main() { AAA::BBB::i; // 必须写出所在命名空间 AAA::j; // 可以直接访问内联命名空间 }
未命名的命名空间:拥有静态生命周期:在第一次使用前创建,直到程序结束后销毁。仅在特定文件内部有效,作业范围不会横跨多个不同文件。
静态声明:将名字声明成static使其对于整个文件有效,用未命名的命名空间实现。
namespace local { namespace { int i; } } local::i =123; // 直接使用。
namespace ABC { namespace EFG {} } namespace A_G = ABC::EFG; // A_G为命名空间ABC::EFG的别名
using声明:一次只引入命名空间的一个成员。如
using std::cout;
using指示:无法控制哪些名字可见,因为都可见。如
using namespace std;。
18.3 多重继承与虚继承
18.3.1 多重继承
如果从多个基类继承了相同的构造函数(形参列表相同),会产生错误。struct D : Base1, Base2 { D(int i) : Base1(i), Base2(i) { } // 对于相同的基类构造函数,需要自定义 }
18.3.4 虚继承
派生类可以多次继承同一个类。会产生多个子对象。虚基类子对象:被虚继承的基类。在派生类中不管出现几次,都只包含唯一一个共享的虚基类子对象。
class B : virtual public A { }; // virtual 和 继承声明位置可以互换 class B : public virtual A { };
相关文章推荐
- C++ 学习笔记(3)命名空间using、字符串、string、vector、迭代器、数组
- C++ Primer学习笔记6 标准库类型(命名空间的using声明、标准库string类型)
- C++学习笔记1(结构体,命名空间,标准输入输出,引用,函数,构造函数)
- c++primer学习笔记-----3.1命名空间的using 声明
- C++ Primer 学习笔记_6_标准库类型 -- 命名空间using与string类型
- C++学习笔记:高级编程:文件和流,异常处理,动态内存,命名空间
- c++中子类的继承和调用父类构造函数的方法——学习c++笔记
- 命名空间、using声明和using指示【附送彩蛋】
- 二 : using声明、using指示用于嵌套命名空间时的作用域
- 二 : using声明、using指示用于嵌套命名空间时的作用域
- C++_命名空间namespace 与 using编译指令 与 using声明使用。
- C++学习笔记(7)——多基类继承的构造函数的调用
- C++基础学习笔记----第五课(动态内存分配、命名空间、强制类型转换)
- C++学习笔记-命名空间
- 【菜鸟C++学习笔记】2.命名空间的作用
- 立此存照(18)[C++]using声明与using指示的区别
- C++学习笔记48——继承中的构造函数
- using声明、using指示用于嵌套命名空间时的作用域
- C++学习6-面向对象编程基础(运算符重载、类的派生与继承、命名空间)
- 【好程序员训练营学习笔记分享8】c++ 继承及构造函数