C++ 什么';s是C+中默认函数的点+;11?
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() {} }; 还是我缺少一个用例?我怀疑能够默认生成复制构造函
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;
可以修改默认函数的以下方面:
- 访问(非公开)
- 虚拟的
- 显式(构造函数)
- 例外规范
- 参数常数
如果您有一个具有许多属性的类,则默认设置对于复制构造函数更有用。 例如,如果您有此类:
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;