零混乱法则? [英] Rule of Zero confusion?

查看:167
本文介绍了零混乱法则?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我一直在阅读有关零规则的信息.

So I have been reading about the Rule of Zero.

简化版:我不了解此规则的目的. 3和5的规则有点像经验法则",但是我看不到经验法则"或任何其他特定意图.

详细版本:

让我引用:

具有自定义析构函数,复制/移动构造函数或 复制/移动分配操作员应专门处理所有权. 其他类不应具有自定义析构函数,请复制/移动 构造函数或复制/移动赋值运算符.

Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership. Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators.

这是什么意思? 所有权是什么,所有权是什么? 他们还显示了示例代码(我想它与简介有关):

What does this mean? What do they mean by ownership, ownership of what? They have also showed an example code(I guess it is connected to the introduction):

class rule_of_zero
{
    std::string cppstring;
 public:
    rule_of_zero(const std::string& arg) : cppstring(arg) {}
};

他们想以此表现什么,我真的迷失了这个.

What do they want to show with this, I am really lost on this one.

此外,他们还讨论了当您处理多态类且析构函数被声明为public和virtual时的情况,以及该块隐式移动的事实.因此,您必须将它们全部声明为默认值:

Also, they are also talking about the scenario when you are dealing with a polymorphic class and the destructor is being declared public and virtual and the fact that this block implicit moves. Therefore, you have to declare them all as defaulted:

class base_of_five_defaults
{
 public:
    base_of_five_defaults(const base_of_five_defaults&) = default;
    base_of_five_defaults(base_of_five_defaults&&) = default;
    base_of_five_defaults& operator=(const base_of_five_defaults&) = default;
    base_of_five_defaults& operator=(base_of_five_defaults&&) = default;
    virtual ~base_of_five_defaults() = default;
};

这是否意味着每当您拥有一个带有声明为public和virtual的析构函数的基类时,您真的必须将所有其他特殊成员函数声明为默认值吗?如果是这样,我不明白为什么.

Does this mean that whenever you have a base class with a destructor that is declared both public and virtual, you really have to declare all the other special member function as defaulted? If so, I do not see why.

我知道这是一个地方的很多困惑.

I know that this is a lot of confusion in one place.

推荐答案

零规则

零规则是关于如何编写需要使用某些资源(如内存或其他对象)的类的另一条经验法则.在该示例中,包含字符串字符的动态分配内存是必须管理的资源.

The rule of zero is another rule of thumb about how to write classes that need to use some resources like memory or other objects. In the example the dynamically allocated memory containing the characters of the string is a resource that has to be managed.

建议让专门的类来管理资源,并仅这样做.在该示例中,std :: string负责管理分配的内存的所有详细信息.

The recommendation is to let specialized classes manage resources, and do only that. In the example, std::string takes care of all the details of managing the allocated memory.

该规则在C ++ 11引入后出现,因为该语言和标准库得到了改进,为管理动态分配的对象生存期(unique_ptr和shared_ptr)提供了更好的工具.现在,容器还允许就地构建,从而消除了动态分配的另一个原因.它可能应该被视为对更老的三个规则的更新.

The rule emerged after the introduction of C++11, because the language and the standard library had improved, providing much better facilities to manage dynamically allocated object lifetimes (unique_ptr and shared_ptr). Also the containers now allow in-place construction, removing another reason for dynamic allocation. It should probably be seen as an update to the much older rule of three.

因此,如果您以前曾在构造函数中使用 new 来创建某些成员,并在析构函数中创建了 delete ,则现在应使用unique_ptr来管理成员,免费"获得搬迁建筑和搬迁任务.

So if you previously would have used new in your constructor to create some member and delete in the destructor, you should now use a unique_ptr to manage the lifetime of the member, getting move construction and move assignment "for free".

共享指针可以记住要调用的正确析构函数,因此,即使是多态使用的对象也完全不需要虚拟析构函数,因为这些对象仅通过共享指针进行管理.

Shared pointers can remember the correct destructor to call, so the common need for a virtual destructor goes away for objects that are exclusively managed via shared pointer, even if they are used polymorphically.

因此,基本上可以依赖其成员执行初始化,移动,复制和销毁操作所需的所有操作的类不应声明任何特殊的成员函数.

So basically a class that can rely on its members to do all the required actions for initialization, moving, copying and destruction should not declare any of the special member functions.

五个规则

与C ++一样,事情并不总是那么简单.

As always with C++ things are not always that simple.

正如Scott Meyers指出的,如果由于某种原因而必须添加析构函数,则即使编译器可以生成隐式生成的Move构造函数和Move赋值运算符,也会被禁用.

As Scott Meyers pointed out, if you do have to add a destructor for whatever reason, the implicit generation of move constructors and move assignment operator are disabled, even if the compiler could generate them.

然后,编译器将快乐地在各处复制您的类,而不是移动它(这可能不是您期望的那样).例如,这可能会减慢您的程序的速度,因为必须执行更多复制.默认情况下,编译器不会对此发出警告.

Then the compiler will happily copy your class all over the place instead of moving it which may not be what you expect. This may for example slow down your program, as more copying has to be performed. The compiler will not warn about this by default.

因此,他建议明确指定要使用的五种特殊方法中的哪一种,以避免因无关的更改而引起意外.他仍然建议编写非资源管理类,以便可以使用编译器生成的默认值.

Therefore he recommends to explicitly specify which of the five special methods you want, in order to avoid surprises due to unrelated changes. He still recommends writing non-resource-management classes such that the defaults generated by the compiler can be used.

这篇关于零混乱法则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆