什么是“违约”?Mean after a class'函数声明?

我曾在类中看到default被用在函数声明旁边。它能做什么?

class C {
C(const C&) = default;
C(C&&) = default;
C& operator=(const C&) & = default;
C& operator=(C&&) & = default;
virtual ~C() { }
};
134907 次浏览

它是c++ 11的新特性

这意味着您希望使用该函数的编译器生成版本,因此不需要指定函数体。

你也可以使用= delete来指定你希望编译器自动生成该函数。

随着move构造函数和move赋值操作符的引入,何时生成构造函数、析构函数和赋值操作符的自动版本的规则变得相当复杂。使用= default= delete让事情变得更简单,因为你不需要记住规则:你只需要说你想发生什么。

这是一个新的c++ 0x特性,它告诉编译器创建各自构造函数或赋值操作符的默认版本,即只对每个成员执行复制或移动操作。这很有用,因为move构造函数并不总是在默认情况下生成(例如,如果你有一个自定义析构函数),这与复制构造函数不同(对于赋值构造函数也是如此),但如果没有什么重要的东西要写,最好让编译器处理它,而不是每次都自己拼写出来。

还要注意,如果您提供任何其他非默认构造函数,则不会生成默认构造函数。如果仍然需要默认构造函数,可以使用此语法让编译器创建一个默认构造函数。

作为另一个用例,有几种情况下,复制构造函数不会隐式生成(例如,如果你提供了一个自定义的移动构造函数)。如果仍然需要默认版本,可以使用以下语法请求它。

详见标准的12.8节。

它是c++ 11中的新元素,参见在这里。如果您已经定义了一个构造函数,但希望对其他构造函数使用默认值,那么它可能非常有用。在c++ 11之前,一旦定义了一个构造函数,就必须定义所有的构造函数,即使它们等同于默认值。

还要注意,在某些情况下,不可能提供一个用户定义的默认构造函数,其行为与编译器在默认的价值初始化下合成的构造函数相同。default允许你得到该行为回来。

我在这些回答中没有看到的另一个用例是,它允许您轻松地更改构造函数的可见性。例如,也许您希望友类能够访问复制构造函数,但又不希望它是公开可用的。

c++ 17 N4659标准草案

https://github.com/cplusplus/draft/blob/master/papers/n4659.pdf 11.4.2 "显式默认函数"

1 .函数定义的形式:

attribute-specifier-seq opt decl-specifier-seq opt declarator virt-specifier-seq opt = default ;

称为显式默认定义。显式默认的函数应

  • (1.1) -是一个特殊的成员函数,

  • (1.2) -具有相同的声明函数类型(除了可能不同的引用限定符和in 对于复制构造函数或复制赋值操作符,形参类型可以是“reference to” 非const T”,其中T是成员函数类的名称),就好像它是隐式声明的一样, 和< / p >

  • (1.3) -没有默认参数。

没有定义为deleted的显式默认函数只有在需要声明为constexpr时才可以声明为 已隐式声明为constexpr。如果函数在第一次声明时显式默认,则为 如果隐式声明为。

,则隐式认为是constexpr

3如果一个显式默认的函数声明了一个noexception -说明符,该noexception -说明符不会产生相同的结果 异常规范作为隐式声明(18.4),然后

  • (3.1) -如果函数在第一次声明时显式默认,则定义为deleted;

  • (3.2) -否则,程序是格式错误的。

< p > 4 (例子:< / p >
struct S {
constexpr S() = default;            // ill-formed: implicit S() is not constexpr
S(int a = 0) = default;             // ill-formed: default argument
void operator=(const S&) = default; // ill-formed: non-matching return type
~ S() noexcept(false) = default;    // deleted: exception specification does not match
private:
int i;                              // OK: private copy constructor
S(S&);
};
S::S(S&) = default;                   // OK: defines copy constructor

- end示例]

5显式默认函数和隐式声明函数统称为默认函数 实现应为它们提供隐式定义(15.1 15.4,15.8),这可能意味着定义 它们被删除了。如果函数是用户声明的,并且没有显式地默认或删除,则该函数是用户提供的 第一次宣布。用户提供的显式默认函数(即,在其第一个函数之后显式默认 声明)在显式默认的地方定义;如果这样的函数被隐式定义为 删除,程序格式不正确。[注意:在函数第一次声明后将其声明为默认值 提供高效的执行和简洁的定义,同时为不断演进的代码提供稳定的二进制接口 基地。- end note]

6[示例:

struct trivial {
trivial() = default;
trivial(const trivial&) = default;
trivial(trivial&&) = default;
trivial& operator=(const trivial&) = default;
trivial& operator=(trivial&&) = default;
~ trivial() = default;
};
struct nontrivial1 {
nontrivial1();
};
nontrivial1::nontrivial1() = default;       // not first declaration

- end示例]

接下来的问题当然是哪些函数可以隐式声明以及何时会发生,我已经在以下部分解释过: