美文网首页C++
=default关键字

=default关键字

作者: Roland | 来源:发表于2015-06-23 16:29 被阅读0次

    =default关键字使用的地方

    The "default" mechanism can be used for any function that has a default. C++11FAQ

    也就是说下面这6个函数都可以跟着=default关键字.

    class A{
    public:
        A() = default; // Default constructor
        A(const A&) = default; // Copy constructor
        A(A&&) = default; // Move constructor(since C++11)
        A& operator=(const A&) = default; // Copy assignment operator
        A& operator=(A&&) = default; // Move assignment operator (since C++11)
        ~A() = default; // Destructor
    };
    

    PS: VS2013暂时不支持Move constructorMove assignment operator使用=default关键字.

    For defaulted functions, using =default to request memberwise move constructors and move assignment operators is not supported. New In VS2013

    =default关键字的作用:显式的要求编译器生成函数的一个默认版本。

    比如说下面的代码,如果用户写了一个构造函数A(int){};,那么就不会为class A生成一个默认的构造函数。这个时候如果用户还需要一个和编译器自动生成的一模一样的默认的构造函数,那么就可以使用=default关键字,显式的让编译器生成一个。

    class A{
    public:
        A(int){};
        A() = default;
        //A(){}; // old way to get an empty constructors like default one.
    };
    

    按照Bjarne的说法,=default的好处在于。这些好处在default constructor上效果不大,但是在Move constructor和Move assignment operator上好处比较大了,因为这两个函数都比较难实现。

    Leaving it to the compiler to implement the default behavior is simpler, less error-prone, and often leads to better object code. C++11FAQ

    写一个=default和写一个空的构造函数有什么区别?

    从执行效果上,=default和一个空的构造函数没有什么区别,都是什么都不做。但是一旦某个类有了一个用户定义的构造函数,那这个类就不再是aggregate类型,和不再是trivial类型,和不再是POD类型了。
    比如说下面这段拷贝至[StackOverflow]的代码所演示的。

    #include <type_traits>
    struct X {
        X() = default;
    };
    
    struct Y {
        Y() {};
    };
    
    int main() {
        static_assert(std::is_trivial<X>::value, "X should be trivial");
        static_assert(std::is_pod<X>::value, "X should be POD");
    
        static_assert(!std::is_trivial<Y>::value, "Y should not be trivial");
        static_assert(!std::is_pod<Y>::value, "Y should not be POD");
    }
    

    另外的不同是,使用=default定义的函数,其constexprexception specification保证了和编译器生成的函数是一致的。而如果要手写的话,就要显式的把constexprexception specification的信息加上。就如下面的代码所示,直接写的A(){}不带有constexpr属性,会导致编译错误。而struct C显式的加上了constexpr就没有编译错误了。
    PS:这代码在VS3013下面没效果,最好用其他编译器来验证。

    struct A{
        A(){}; 
    };
    struct B{
        B() = default;
    };
    struct C{
        constexpr C(){};
    };
    
    constexpr int f(A s){ return 0; } // compiling error here
    constexpr int f(B s){ return 0; }
    constexpr int f(C s){ return 0; }
    

    写一个=default和直接不写构造函数有什么区别。

    第一眼看到=default的感觉就是,这是多余的嘛,和直接不写也没有区别嘛。后来想了下,在下面的这种情况下,=default还是有用处的。

    class A{   
    public:
        static A* CreateA() { return new A; }
    private:
        A() = default;
    };
    

    在这个类中,我们希望使用类的某个默认函数,但是需要控制这个函数的访问权限。 在这里的代码使用默认的构造函数为例子。这个时候=default就有用了,如果什么都不写的话,这些默认函数的作用域是public。使用=default可以很方面的想编译器在public作用域下生成这个函数。在没有=defaultC++03时代,处理这种问题,就需要程序员自己写个完整的实习出来,对于默认构造函数来说,还比较简单,如果对于写个Copy assignment operator,还是不小的工作量的,也容易出错。
    [StackOverflow]:http://stackoverflow.com/questions/20828907/the-new-keyword-default-in-c11

    相关文章

      网友评论

        本文标题:=default关键字

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