• Type Alias、noexcept、override、final


    Type Alias (similar to typedef)

    // typedef void (*func)(int, int)
    using func = void (*) (int, int);
    
    // the name 'func' now denotes a pointer to function:
    void example(int, int){}
    
    func fn = example; // func 就是函数指针类型 是一个 type 哦!!!
    

    noexcept

    void foo() noexcept; // => void foo() noexcept(true);
    // 表示 foo 函数保证不会抛出异常,如果 foo 产生了异常,又声明了 noexcept 那么程序会调用 std::terminate(),std::terminate() 调用 std::abort()
    
    // 你甚至可以指定一个特殊的条件,在该条件下保证函数不会抛出异常:
    template<typename T>
    void swap(T &x, T &y) noexcept(noexcept(x.swap(y))) {
        x.swap(y);
    }
    // 在 noexcept(...) 括号内部,可以放入一个 bool 条件,表示在该条件成立(True)的情况下保证不抛出异常
    

    You need to inform C++(specifically std::vector) that your move ctor and dtor does not throw. Then the move ctor will be called when the vector grows. If the move ctor is not noexcept, std::vector can't use it, since then it can't ensure the exception guarantees demanded by the standard.

    注意:growable containers(会发生 memory reallocation) 只有两者:vector 和 dequee

    class MyString{
    private:
        char *_data;
        size_t _len;
        ···
    public:
        //move ctor
        // move ctor 效率比 copy ctor 高不少,所以对于 growable 的 container 来说,一旦reallocation 发生时用 move ctor 会高效不少,但是一定要保证 noexcept 因为 container 无法自己解决 exception
    
        MyString(MyString&& str) noexcept
        : _data(str._data), _len(str._len) {···}
    
        //move assignment
        MyString& operator=(MyString&& str) noexcept
        {··· return *this;}
    
    ···
    };
    

    override

    struct Base{
        virtual void func(float){}
    };
    
    struct Derived1:Base{
        virtual void func(int){}
            // accidentally create a new virtual function, when one intended to override a base class function
    };
    
    struct Derived2:Base{
        virtual void func(int) override {}
        // [Error] 'virtual void Derived2::func(int)' marked override, but doesn't override 
        // key word 'override' means that the compiler will check the base class to see if there is a virtual function with this exact signature.
        // And if there is not, the compiler will indicate an error.
        virtual void func(float) override {}
    };
    

    final

    struct Base1 final {}; // 此处 final 表示不能被继承
    
    struct Derived1 : Base1 {};
     //[Error] cannot derive from 'final' base 'Base1' in derived type 'Derived1'
    
    struct Base2 {
         virtual void f() final; // 此处 final 表示函数 f 不能被 override
     };
    
    struct Derived2 : Base2 {
        void f();
        // [Error] overriding final function 'virtual void Base2::f()'
    };
    
  • 相关阅读:
    c++11-17 模板核心知识(七)—— 模板参数 按值传递 vs 按引用传递
    c++11-17 模板核心知识(六)—— 理解auto推导规则
    c++11-17 模板核心知识(五)—— 理解模板参数推导规则
    c++11-17 模板核心知识(四)—— 可变参数模板 Variadic Template
    c++11-17 模板核心知识(三)—— 非类型模板参数 Nontype Template Parameters
    c++11-17 模板核心知识(二)—— 类模板
    c++11-17 模板核心知识(一)—— 函数模板
    Docker修改Devicemapper存储驱动为Direct-lvm模式
    Linux配置/etc/resolv.conf详解
    深入浅出容器学习--Docker网络
  • 原文地址:https://www.cnblogs.com/Codroc/p/13998458.html
Copyright © 2020-2023  润新知