C++ 什么';s是C+中默认函数的点+;11?

C++ 什么';s是C+中默认函数的点+;11?,c++,c++11,defaulted-functions,C++,C++11,Defaulted Functions,C++11增加了告诉编译器使用任何。虽然我可以看到删除函数的值,但显式默认函数的值在哪里?只需将其保留为空,编译器就会执行该操作 我能看到的唯一一点是,只有在不存在其他构造函数的情况下才会创建默认构造函数: class eg { public: eg(int i); eg() = default; }; 但这真的比你现在做的好吗 class eg { public: eg(int i); eg() {} }; 还是我缺少一个用例?我怀疑能够默认生成复制构造函

C++11增加了告诉编译器使用任何。虽然我可以看到删除函数的值,但显式默认函数的值在哪里?只需将其保留为空,编译器就会执行该操作

我能看到的唯一一点是,只有在不存在其他构造函数的情况下才会创建默认构造函数:

class eg {
public:
    eg(int i);
    eg() = default; 
};
但这真的比你现在做的好吗

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

还是我缺少一个用例?

我怀疑能够默认生成复制构造函数实际上是有用的。我看不到默认生成默认构造函数的用途,因为正如您所说,您键入的实现将更短。

对我来说,禁用功能将非常有用,对于我当前创建的大多数类,我禁用复制和赋值-如果有一个编译器能够识别的功能来执行此操作,那将非常好,而不是依赖链接器错误。

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

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

默认和删除的函数--控制默认值

“禁止”这句俗语 现在可以表示为“复制” 直接:

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 S
{
    virtual ~S();
    virtual S& operator=(const S&);
};

S::~S() = default;
S& S::operator=(const S&) = default;
可以修改默认函数的以下方面:

  • 访问(非公开)
  • 虚拟的
  • 显式(构造函数)
  • 例外规范
  • 参数常数
但要做到这一点,必须在类之外定义函数(中为8.4.2/2)

劳伦斯·克罗尔(Lawrence Crowl)最初提议的一个版本是

感谢您的澄清和引用。

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

2) 与隐式生成的访问说明符相反,它们将具有访问说明符

3) 如果您内联默认的构造函数,那么您的类仍然是微不足道的


如果您有一个具有许多属性的类,则默认设置对于复制构造函数更有用。 例如,如果您有此类:

class-MyClass{
私人:
整数偏移量;
std::字符串名;
std::病媒亲属;
浮重;
MyClass*配偶;
车辆*汽车;
双户型面积;
出生日期;
个人*父母[2];
公众:
/*默认构造函数将在此处定义*/
};
不要这样定义复制构造函数:

MyClass(const MyClass&that):
偏移量(即偏移量),
姓名(即姓名),
亲属(即亲属),,
重量(即重量),
配偶(即配偶),
车(那辆车),,
房屋面积(即房屋面积),
出生(即出生),
父母(即父母)
{}
您可以这样定义:

MyClass(const MyClass&)=默认值;

请参阅斯科特·迈耶(Scott Meyer)的巨著“第17项”。它描述了生成(或不生成)默认复制构造函数、复制操作和移动操作的许多条件

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

根据第17项结尾处要记住的事情:

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

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


实际上,我是在阅读了BS的C++0x常见问题之后问这个问题的,他的“明显多余”的评论促使我对整个默认问题提出了质疑。嗯,bummer你可以在任何事情上使用=delete,但不能使用=default。如果从一个不可复制的类派生,那么即使现在(C++98),您也会喜欢编写“int main()=default;//返回到读取StackOverflow”,您可以让编译器检测错误(即使在类本身中使用)而且不必等待链接时间。我不相信引入派生来解决这样的问题。为什么gcc 4.5.0会为您发布的代码发出以下错误:“virtual S::~S()”声明的virtual不能在类中默认body@bpw:因为8.4.2/2(在N3092中签入)明确禁止此代码。@罗杰,谢谢(其他地方)的澄清。正如您所指出的,我已经在类之外定义了函数。在类主体中定义函数是否会引起一些歧义?你这样做似乎很奇怪
struct S
{
    virtual ~S();
    virtual S& operator=(const S&);
};

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