美文网首页
C++11——大型程序工具

C++11——大型程序工具

作者: 铭小汁儿 | 来源:发表于2019-05-15 11:22 被阅读0次

    noexcept异常标识符

    在新标准下,函数可以通过提供noexcept标识符来指定它不会抛出异常。函数参数列表后面的关键字noexcept表示该函数不会抛出:

    Code:
        void recoup(int) noexcept;  // won't throw
        void alloc(int);            // might throw
    

    上述代码中recoup不会抛出任何异常,而alloc可能会抛出异常。我们说recoup有一个非nonthrowing specification。
    noexcept说明符必须出现在所有声明和函数的相应定义上,或者不出现在任何声明上。说明符在尾随返回之前。我们还可以在函数指针的声明和定义上指定noexcept。它可能不会出现在typedef或类型别名中。在成员函数中,noexcept说明符跟随在任何const或引用限定符之后,并且它在虚函数上的finaloverride= 0之前。

    noexcept运算符

    noexcept说明符的参数通常使用noexcept运算符构成。noexcept运算符是一元运算符,它返回一个bool类型的右值常量表达式,指示给定表达式是否可能抛出。与sizeof一样,noexcept不计算其操作数。
    例如,下面的表达式将得到true

    Code:
        noexcept(recoup(i)) // true if callingrecoup can't throw, false otherwise
    

    因为我们用noexcept说明符声明了recoup。更一般的:

    Code:
        noexcept(e)
    

    如果e调用的所有函数都具有非抛出标识符且e本身不包含throw,则上式为true。否则上式返回false
    我们可以使用noexcept运算符来形成异常说明符,如下所示:

    Code:
        void f() noexcept(noexcept(g())); // f has same exception specifier as g
    

    如果函数g承诺不抛出,则f也是非抛出的。如果g没有异常说明符,或者有一个允许异常的异常说明符,那么f也可能抛出。
    注:noexcept有两个含义:当它跟随在函数的参数列表之后时,它是一个异常说明符;当用作noexcept异常说明符的bool参数时,它是一个运算符。

    内联命名空间

    新标准引入了一种新的嵌套命名空间,即内联命名空间。与普通的嵌套命名空间不同,内联命名空间中的名称可以像使用封闭命名空间的直接成员一样使用。也就是说,我们不需要通过命名空间名称限定内联命名空间中的名称。我们只能使用封闭命名空间的名称来访问它们。
    内联命名空间是通过在关键字namespace前面加上关键字inline来定义的:

    Code:
        inline namespace FifthEd {
            // namespace for the code from the Primer Fifth Edition
        }
        namespace FifthEd { // implicitly inline
            class Query_base { /* ... * /};
            // other Query-related declarations
        }
    

    关键字inline必须出现在命名空间的第一个定义中。如果后面重新打开命名空间,则关键字inline不是必须的,但可以重复使用。
    当代码从应用程序的一个版本更改为下一个版本时,通常会使用内联命名空间。例如,我们可以将当前版本的Primer中的所有代码放入内联命名空间。以前版本的代码将位于非内联命名空间中:

    Code:
        namespace FourthEd {
            class Item_base { /* ... */};
            class Query_base { /* ... */};
            // other code from the Fourth Edition
        }
    

    整个cplusplus_primer命名空间将包括两个命名空间的定义。例如,假设每个命名空间都在具有相应名称的头文件中定义,我们将cplusplus_primer定义如下:

    Code:
        namespace cplusplus_primer {
        #include "FifthEd.h"
        #include "FourthEd.h"
        }
    

    因为FifthEd是内联的,所以引用cplusplus_primer::的代码将从该命名空间获取版本。如果我们想要早期版本的代码,我们可以像使用任何其他嵌套命名空间一样访问它,方法是使用所有封闭命名空间的名称:例如:

    Code:
        cplusplus_primer::FourthEd::Query_base
    

    继承的构造函数和多重继承

    在新标准下,派生类可以从一个或多个基类继承其构造函数。从多个基类继承相同的构造函数(即具有相同参数列表的构造函数)是错误的:

    Code:
        struct Base1 {
            Base1() = default;
            Base1(const std::string&);
            Base1(std::shared_ptr<int>);
        };
        struct Base2 {
            Base2() = default;
            Base2(const std::string&);
            Base2(int);
        };
        // error: D1 attempts to inherit D1::D1 (const string&) from both base classes
        struct D1: public Base1, public Base2 {
            using Base1::Base1;  // inherit constructors from Base1
            using Base2::Base2;  // inherit constructors from Base2
        };
    

    从多个基类继承相同构造函数的类必须定义其自己的构造函数版本:

    Code:
        struct D2: public Base1, public Base2 {
            using Base1::Base1;  // inherit constructors from Base1
            using Base2::Base2;  // inherit constructors from Base2
            // D2 must define its own constructor that takes a string
            D2(const string &s): Base1(s), Base2(s) { }
            D2() = default;     // needed once D2 defines its own constructor
        };
    

    参考文献

    [1] Lippman S B , Josée Lajoie, Moo B E . C++ Primer (5th Edition)[J]. 2013.

    相关文章

      网友评论

          本文标题:C++11——大型程序工具

          本文链接:https://www.haomeiwen.com/subject/jwwuaqtx.html