四(半)规则是什么? [英] What is the Rule of Four (and a half)?

查看:112
本文介绍了四(半)规则是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了正确处理对象复制,经验法则是三人制规则.在C ++ 11中,移动语义是一回事,因此它是五人制.但是,在围绕此处和互联网的讨论中,我也看到了对

For properly handling object copying, the rule of thumb is the Rule of Three. With C++11, move semantics are a thing, so instead it's the Rule of Five. However, in discussions around here and on the internet, I've also seen references to the Rule of Four (and a half), which is a combination of the Rule of Five and the copy-and-swap idiom.

那么四个(半个)规则到底是什么?需要实现哪些功能,每个功能的主体应该是什么样?一半是哪个功能?与五法则相比,这种方法是否有任何弊端或警告?

So what exactly is the Rule of Four (and a half)? Which functions need to be implemented, and what should each function's body look like? Which function is the half? Are there any disadvantages or warnings for this approach, compared to the Rule of Five?

这是一个类似于我当前代码的参考实现.如果这是不正确的,那么正确的实现将是什么样子?

Here's a reference implementation that resembles my current code. If this is incorrect, what would a correct implementation look like?

//I understand that in this example, I could just use `std::unique_ptr`.
//Just assume it's a more complex resource.
#include <utility>

class Foo {
public:
    //We must have a default constructor so we can swap during copy construction.
    //It need not be useful, but it should be swappable and deconstructable.
    //It can be private, if it's not truly a valid state for the object.
    Foo() : resource(nullptr) {}

    //Normal constructor, acquire resource
    Foo(int value) : resource(new int(value)) {}

    //Copy constructor
    Foo(Foo const& other) {
        //Copy the resource here.
        resource = new int(*other.resource);
    }

    //Move constructor
    //Delegates to default constructor to put us in safe state.
    Foo(Foo&& other) : Foo() {
        swap(other);
    }

    //Assignment
    Foo& operator=(Foo other) {
        swap(other);
        return *this;
    }

    //Destructor
    ~Foo() {
        //Free the resource here.
        //We must handle the default state that can appear from the copy ctor.
        //(The if is not technically needed here. `delete nullptr` is safe.)
        if (resource != nullptr) delete resource;
    }

    //Swap
    void swap(Foo& other) {
        using std::swap;

        //Swap the resource between instances here.
        swap(resource, other.resource);
    }

    //Swap for ADL
    friend void swap(Foo& left, Foo& right) {
        left.swap(right);
    }

private:
    int* resource;
};

推荐答案

那么四个(半个)规则到底是什么?

So what exactly is the Rule of Four (and a half)?

四大(半个)规则"指出,如果您实现其中一个

"The Rule of The Big Four (and a half)" states that if you implement one of

  • 复制构造函数
  • 赋值运算符
  • 移动构造函数
  • 破坏者
  • 交换功能

那你必须对其他人有一个政策.

then you must have a policy about the others.

需要实现哪些功能,每个功能的主体应该是什么样?

Which functions need to implemented, and what should each function's body look like?

  • 默认构造函数(可以是私有的)
  • 复制构造函数(这里有用于处理资源的真实代码)
  • 移动构造函数(使用默认构造函数和交换):

    • default constructor (which could be private)
    • copy constructor (Here you have real code to handle your resource)
    • move constructor (using default constructor and swap) :

      S(S&& s) : S{} { swap(*this, s); }
      

    • 赋值运算符(使用构造函数和交换)

    • assignment operator (using constructor and swap)

      S& operator=(S s) { swap(*this, s); }
      

    • 析构函数(资源的深层副本)

    • destructor (deep copy of your resource)

      哪个功能是一半?

      Which function is the half?

      上一篇文章:

      要实现Copy-Swap惯用语,您的资源管理类还必须实现swap()函数以执行逐成员交换(其中有您的…(一半)")"

      "To implement the Copy-Swap idiom your resource management class must also implement a swap() function to perform a member-by-member swap (there’s your "…(and a half)")"

      swap方法.

      与五法则"相比,这种方法是否有任何弊端或警告?

      Are there any disadvantages or warnings for this approach, compared to the Rule of Five?

      我已经写过的警告即将编写正确的交换,以避免无限递归.

      The warning I already wrote is about to write the correct swap to avoid the infinite recursion.

      这篇关于四(半)规则是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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