• C++ Primer学习笔记-----第十八章:用于大型程序的工具


    1.异常处理

    try
    {
    	try
    	{
    	}
    	catch(bad_alloc)	//捕获特定异常
    	{
    		/**处理异常**/			
    		throw;			//或者抛出,让外层的异常捕获处理
    	}
    }
    catch(...)	//捕获所有内存未处理的异常
    {
    	/**处理异常**/
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    1.3.函数try语句块与构造函数

    构造函数在进入其函数体之前首先执行初始值列表。如果在函数体内部捕获异常,因为在初始值列表抛出异常时构造函数体内的try
    语句块还未生效,所以构造函数体内的catch语句无法处理构造函数初始值列表抛出的异常。
    
    函数try语句块使得一组catch语句既能处理构造函数体(或析构函数体),也能处理构造函数的初始化过程(或析构函数的析构过程)。
    例如:
    template<typename T>
    Test<T>::Test(std::initializer_list<T> il) try:vec(il)	
    {	/**空函数体**/  }
    catch(const std::bad_alloc &e)
    {	/**处理异常**/	}
    
    还有一种情况值得注意,在初始化构造函数的参数时也可能发生异常,这样的异常不属于函数try语句块的一部分。函数try语句块
    只能处理构造函数开始执行后发生的异常。和其他函数调用一样,如果在参数初始化的过程中发生了异常,则该异常属于调用表达式
    的一部分,并将在调用者所在的上下文中处理。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.4.noexcept异常说明

    对于用户即编译器来说,预先指定某个函数不会抛出异常显然大有裨益。
    首先,知道函数不会抛出异常有助于简化调用该函数的代码;
    其次,如果编译器确认函数不会抛出异常,它就能执行某些特殊的优化操作。
    
    void fun()const & noexcept override {}typedef或类型别名中则不能出现noexcept.
    在成员函数中,noexcept说明符需要跟在const及引用限定符后,而在finaloverride或虚函数=0之前。
    所以的声明和定义都要有noexcept,或者都没有。
    
    noexcept可以用在两种情况下:
    1.确认函数不会抛出异常。
    2.根本不知道如何处理异常。
    编译器并不会在编译时检查noexcept说明。
    
    下面两个函数等价:都不会抛出异常
    void fun() noexcept;	
    void fun() throw();		//旧版本
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    异常说明的实参

    noexcept说明符接受一个可选的实参,该实参必须能转换为bool类型。
    void fun() noexcept(true);		//不抛出异常
    
    • 1
    • 2

    noexcept运算符

    noexcept运算符是一个一元运算符,返回值是一个bool类型的右值常量表达式,表示给定的表达式是否会抛出异常。
    和sizeof类似,noexcept也不会求运算对象的值。
    noexcept(e)
    当e调用的所有函数都做了不抛出说明且e本身不含有throw语句时,上述表达式为true,否则返回falsevoid f() noexcept(noexcept(g()));	//外层的noexcept是异常说明符,内层的是操作符。
    f和g的异常说明一致:要异常都异常,不异常都不异常。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    异常说明与指针、虚函数和拷贝控制

    尽管noexcept说明符不属于函数类型的一部分,但是函数的异常说明仍然会影响函数的使用。
    函数指针及该指针所指的函数必须具有一致的异常说明。也就是说,如果我们为某个指针做了不抛出异常的说明,则该指针将只能
    指向不抛出异常的函数。如果显示或隐式说明了指针可能抛出异常,则该指针可以指向任何函数。
    
    如果一个虚函数承诺它不会抛出异常,则后续派生出来的虚函数也必须做出同样的承诺。
    如果基类的虚函数允许抛出异常,则派生类的对应函数既可以抛出异常,也可以不抛出异常。
    
    当编译器合成拷贝控制成员时,同时也生成一个异常说明。如果对所有成员和基类的所有操作都承诺不会抛出异常,则合成的成员
    是noexcept的。如果合成成员调用的任意一个函数可能抛出异常,则合成的成员是noexcept(false).而且,如果我们定义了一个
    析构函数但是没有为它提供异常说明,则编译器将合成一个。合成的异常说明将与假设由编译器为类合成析构函数时所得的异常
    说明一致。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    1.5.异常类层次
    在这里插入图片描述
    可以定义自己的异常类

    class MyExcept:public std::runtime_error
    {
    public:
    	explicit MyExcept(const std::string& s):std::runtime_error(s){}
    }
    
    class MyExcept2:public std::logic_error
    {
    public:
    	explicit MyExcept(const std::string& s,const std::string& s2):std::runtime_error(s),str(s2){}
    	const std::string str;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.命名空间

    #include 
    namespace ns
    {
    	namespace ns2{}
    	inline namespace ns1{}	//内联命名空间,外层作用域可直接访问内部的成员	
    	namespace{}				//未命名命名空间,可直接访问成员,每个文件的未命名命名空间不同
    }
    
    namespace myns = ns::ns2;	//简化命名空间命名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    using声明:扼要概述

    一条using声明语句一次只引入命名空间的一个成员。
    using ns::meb;
    
    • 1
    • 2

    using指示:把命名空间中的成员注入外层作用域中

    using namesapce ns;	//ns命名空间所有的名字都可见,这样就无须添加任何前缀限定符了
    
    • 1

    3.多重继承与虚继承

    class Base{}
    class Derived1:public virtual Base{}		//虚继承
    class Derived2:public virtual Base{}		//虚继承
    class SubDerived:public Derived1,public Derived2	//SubDerived中只有一份Base成员
    {
    public:
    	SubDerived():Base(),Derived1(),Derived2(){}	//直接调用虚基类的构造函数,进行初始化
    }	
    
    初始化:先初始化虚基类的成员(调用虚基类的构造函数),在顺序初始化其他直接基类。
    析构:最后执行虚基类的析构函数。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    Molecular Psychiatry:神经成像预测模型在心理健康领域的未来趋势
    【c++】c++类的大小的计算和this指针
    Text-based diagram tool
    C++11智能指针
    CF1381D The Majestic Brown Tree Snake
    JAVA中常用序列化与反序列化合集
    PyBind11踩坑笔记
    2.6 动态规划—lc炒股系列
    五金机电行业S2B2B商城系统打破传统线下营销方式,实现企业高质量发展
    什么是分布式锁?几种分布式锁分别是怎么实现的?
  • 原文地址:https://blog.csdn.net/weixin_41155760/article/details/126142354