C++11 添加了告诉编译器的功能 创建默认实现 任何一个的 特殊会员功能. 。虽然我可以看到删除函数的价值,但显式默认函数的价值在哪里?只要将其留空,编译器无论如何都会执行此操作。

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

class eg {
public:
    eg(int i);
    eg() = default; 
};

但这真的比现在更好吗?

class eg {
public:
    eg(int i);
    eg() {}
};

或者我错过了一个用例?

有帮助吗?

解决方案

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

其他提示

Stroustrup的网站中的这些示例可能有助于您理解这一点:

  

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

     

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

class X {
  // ...

  X& operator=(const X&) = delete;    // Disallow copying
  X(const X&) = delete;
};
     

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

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

};
     

明确默认是   显然多余,但评论   这种影响和(更糟糕的)用户   明确定义复制操作   意味着给出默认行为   并不罕见。离开它   编译器实现默认值   行为更简单,更不容易出错,   并经常导致更好的目标代码。   “默认”是指“默认”。可以使用机制   对于任何具有默认值的函数。   “删除”机制可以用于   任何功能。例如,我们可以   消除不希望的转换,如   这样:

struct Z {
  // ...

  Z(long long);     // can initialize with an long long
  Z(long) = delete; // but not anything less
};

除了更改生成函数的可访问性(私有/受保护)之外,您还可以使它们虚拟化。

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

S::~S() = default;
S& S::operator=(const S&) = default;

可以修改默认功能的以下方面:

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

但要做到这一点,函数必须在类之外定义(8.4.2/2 中 C++0x 最终委员会草案).

劳伦斯·克劳尔 (Lawrence Crowl) 原始提案的一个版本是 这里.

谢谢 罗杰·佩特 用于澄清和引用。

1)隐式生成的析构函数目前不是虚拟的。所以你需要定义它们以使它们成为虚拟的,在这种情况下它们不那么有效。使用= default,您将同时拥有virtual和efficent作为隐式生成的析构函数。

2)他们将拥有访问说明符,与隐式生成的说明符相反。

3)如果你内联你的默认构造函数,你的课仍然是微不足道的。

这是一篇详细阐述这一新功能的文章。

我怀疑能够默认生成复制构造函数实际上是有用的。我看不到默认生成默认构造函数的用法,因为你说你输入的实现会更短。

请参阅 Scott Meyer 的伟大著作中的第 17 条“有效的现代 C++”。它描述了生成(或不生成)默认复制构造函数、复制操作和移动操作的许多条件。

换句话说,编译器可能不会“无论如何都这样做”。但是,如果默认的特殊成员函数有意义,则用户可以使用“default”关键字显式告诉编译器生成默认函数,否则不会生成该默认函数。

第 17 条末尾的“要记住的事情”:

  • 仅针对缺少显式声明的移动操作、复制操作或析构函数的类生成移动操作。

  • 复制构造函数仅针对缺少显式声明的复制构造函数的类生成,并且如果声明了移动操作,则复制构造函数将被删除。复制赋值运算符仅针对缺少显式声明的复制赋值运算符的类生成,并且如果声明了移动操作,则该运算符将被删除。不推荐在具有显式声明的析构函数的类中生成复制操作。

对我来说,它的禁用功能非常有用,对于我目前创建的大多数类,我禁用了复制和放大功能。赋值 - 拥有编译器可以识别的功能,而不是依赖于链接器错误,这将是很好的。

如果您有一个包含大量属性的类,则默认对复制构造函数更有用。 例如,如果您有这个类:

class MyClass {
private:
   int offset;
   std::string name;
   std::vector<Person*> relatives;
   float weight;
   MyClass* spouse;
   Vehicle* car;
   double houseArea;
   Date birth;
   Person* parents[2];

public:
   /* Default constructor will be defined here */
};

而不是以这种方式定义复制构造函数:

MyClass(const MyClass& that) :
   offset(that.offset),
   name(that.name),
   relatives(that.relatives),
   weight(that.weight),
   spouse(that.spouse),
   car(that.car),
   houseArea(that.houseArea),
   birth(that.birth),
   parents(that.parents)
{}

你会这样定义:

MyClass(const MyClass&) = default;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top