据我所知,这些语义仅用于复制构造函数,移动构造函数,复制赋值,移动赋值和析构函数.使用= delete是禁止使用其中一个函数,= default如果您希望在编译器上明确使用这些函数的默认值,则使用它.
在上课时使用这些关键字的最佳做法是什么?或者更确切地说,在开发课程时如何注意这些?
例如,如果我不知道我是否会使用其中一种功能,最好是禁止使用它delete还是允许它使用default?
好问题.
同样重要的是: 在哪里使用= default和= delete.
我对此有一些有争议的建议.它与我们所学到的(包括我自己)C++ 98/03 相矛盾.
与您的数据成员一起开始您的课程声明:
class MyClass
{
std::unique_ptr<OtherClass> ptr_;
std::string name_;
std::vector<double> data_;
// ...
};
Run Code Online (Sandbox Code Playgroud)
然后,尽可能接近,列出要显式声明的所有六个特殊成员,并以可预测的顺序列出(并且不列出您希望编译器处理的那些成员).我更喜欢的顺序是:
// this tells me the very most important things about this class.// I like to see my copy members together// I like to see my move members together这个订单的原因是:
例如:
class MyClass
{
std::unique_ptr<OtherClass> ptr_;
std::string name_;
std::vector<double> data_;
public:
MyClass() = default;
MyClass(const MyClass& other);
MyClass& operator=(const MyClass& other);
MyClass(MyClass&&) = default;
MyClass& operator=(MyClass&&) = default;
// Other constructors...
// Other public member functions
// friend functions
// friend types
// private member functions
// ...
};
Run Code Online (Sandbox Code Playgroud)
知道了约定,人们可以很快地看到,而不必检查~MyClass()隐式默认的整个类声明,并且附近的数据成员很容易看到编译器声明和提供的析构函数的作用.
接下来我们可以看到它MyClass有一个显式默认的默认构造函数,并且附近声明了数据成员,很容易看到编译器提供的默认构造函数的作用.很容易理解为什么默认构造函数已被显式声明:因为我们需要一个用户定义的复制构造函数,如果没有明确默认,这将禁止编译器提供的默认构造函数.
接下来我们看到有一个用户提供的复制构造函数和复制赋值运算符.为什么?好吧,随着附近的数据成员,很容易推测可能需要深层次的数据unique_ptr ptr_.我们当然不知道当然没有检查复制成员的定义.但即使没有这些定义也很方便,我们已经非常了解情况.
对于用户声明的复制成员,如果我们什么也不做,则隐式不会移动成员.但是在这里我们很容易看到(因为所有内容都可以预见地在MyClass声明的顶部进行分组和排序),我们已明确默认移动成员.再次,因为数据成员在附近,我们可以立即看到这些编译器提供的移动成员将做什么.
总之,我们还没有确切知道MyClass它将在这个计划中扮演什么角色和角色.然而,即使缺乏这些知识,我们已经知道了很多MyClass.
我们知道MyClass:
OtherClass.ptr_,空name_和data_.在10行左右的代码中可以了解很多.而且我们不必去寻找数百行代码,我肯定需要这些代码才能正确实现MyClass以学习所有这些:因为它全部位于顶层且可预测的顺序.
有人可能想要调整此配方,以便在数据成员之前放置嵌套类型,以便可以根据嵌套类型声明数据成员.但是,这一建议的精神是宣布私人数据成员和特殊成员,尽可能接近顶端,并尽可能接近彼此.这与过去给出的建议(可能甚至是我自己)相反,私有数据成员是一个实现细节,不足以成为类声明的顶端.
但事后看来(后见之明总是20/20),私有数据成员,即使远程代码无法访问(这是一件好事),当任何特殊成员编译器提供时,它会指示和描述类型的基本行为. .并且知道班级的特殊成员所做的事情,是理解任何类型的最重要方面之一.
每种类型都有这些问题的答案,最好尽快解决这些问题和答案.然后你可以更容易地专注于使这种类型与其他类型不同的东西.