=default修饰函数

=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 constructor和Move 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定义的函数,其constexpr 和 exception specification保证了和编译器生成的函数是一致的。而如果要手写的话,就要显式的把constexpr 和 exception 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作用域下生成这个函数。在没有=default的C++03时代,处理这种问题,就需要程序员自己写个完整的实习出来,对于默认构造函数来说,还比较简单,如果对于写个Copy assignment operator,还是不小的工作量的,也容易出错。

原文链接:http://www.jianshu.com/p/f964b929f2bc
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值