C++ 11中默认函数的重点是什么?

Mot*_*tti 19 c++ defaulted-functions c++11

C++ 11增加了告诉编译器创建任何特殊成员函数的默认实现的能力.虽然我可以看到删除函数的价值,但显式默认函数的值是什么?只需将其留空,编译器无论如何都会这样做.

我能看到的唯一一点是,只有当没有其他构造函数存在时才会创建默认构造函数:

class eg {
public:
    eg(int i);
    eg() = default; 
};
Run Code Online (Sandbox Code Playgroud)

但这真的比你现在这样做好吗?

class eg {
public:
    eg(int i);
    eg() {}
};
Run Code Online (Sandbox Code Playgroud)

或者我错过了一个用例?

MSa*_*ers 19

默认构造函数将具有声明,并且该声明将受到正常访问规则的约束.例如,您可以使默认的复制构造函数受到保护.如果没有这些新声明,默认生成的成员将是公共的.

  • [dig]另外:定义某些特殊成员函数会阻止编译器默认其他函数,但可以使用= default重新启用它.例如,如果实现自定义复制构造函数,则不会生成默认移动构造函数.您可以自己明确地默认它,而不是自己实现它. (5认同)

Kla*_*aim 17

来自Stroustrup网站的这些例子可能会帮助您理解这一点:

默认和删除的功能 - 默认控制

现在可以直接表达"禁止复制"的常用习语:

class X {
  // ...

  X& operator=(const X&) = delete;    // Disallow copying
  X(const X&) = delete;
};
Run Code Online (Sandbox Code Playgroud)

相反,我们也可以明确地说我们想要默认的复制行为:

class Y {
  // ...
  Y& operator=(const Y&) = default;   // default copy semantics
  Y(const Y&) = default;

};
Run Code Online (Sandbox Code Playgroud)

明确关于默认值显然是多余的,但是对这种效果的评论以及(更糟糕的)明确定义复制操作的用户意味着给出默认行为并不罕见.将它留给编译器来实现默认行为更简单,更不容易出错,并且通常会导致更好的目标代码."默认"机制可用于任何具有默认值的函数."删除"机制可用于任何功能.例如,我们可以消除不需要的转换,如下所示:

struct Z {
  // ...

  Z(long long);     // can initialize with an long long
  Z(long) = delete; // but not anything less
};
Run Code Online (Sandbox Code Playgroud)

  • 嗯,你可以使用=删除任何东西但不是=默认.本来喜欢写"int main()= default; //回去阅读StackOverflow" (8认同)

Jam*_*kin 12

除了更改生成函数的可访问性(私有/受保护)之外,您还可以将它们设置为虚拟.

struct S
{
    virtual ~S();
    virtual S& operator=(const S&);
};

S::~S() = default;
S& S::operator=(const S&) = default;
Run Code Online (Sandbox Code Playgroud)

可以修改默认函数的以下方面:

  • 访问(非公开)
  • 虚拟
  • 显式(构造函数)
  • 例外规范
  • 参数的常数

但要这样做,必须在课外定义函数(C++ 0x最终委员会草案中的8.4.2/2 ).

劳伦斯·克劳尔的原始提案版本就在这里.

感谢Roger Pate的澄清和引用.

  • 这个限制不再适用于较新的草稿(N3376对我来说和顺序C++ 14草稿).所以你可以声明`virtual~Class()= default`. (7认同)
  • 在类体中定义它是否会引起一些歧义?看起来奇怪的是你可以在Class的主体中说`virtual~Class(){}`,但不是`virtual~Class()= default;`在任何情况下,这两段代码之间的行为有什么不同吗? (2认同)