rule of three

rule of three or rule of five(額外多move). 此rule是根據rules of thumb in C++所產生
主要是為了預防再做資源管理時發生不可預期的錯誤, 所建議的撰寫規則.
如下為一個經由給定(=)後所產生的double free問題.

#include <iostream>
#include <string>

class ResourceFreeFailed
{
    private:
        char *m_str;
    public:
        ~ResourceFreeFailed()
        {
            delete [] m_str;
        }
        ResourceFreeFailed() = default;
        ResourceFreeFailed(const char *pstr) : m_str(new char[128])
        {
            std::strcpy(m_str, pstr);
        }
};

int main()
{
    ResourceFreeFailed c("resource");
    {
        // d will release resource of c
        ResourceFreeFailed d;
        // ERROR: assign c to d
        d = c;
    }
    // c will release resource, but someting is wrong

    return 0;
}

[1][2]定義了兩種情況,在撰寫class時候需要記得此規則:

  1. 撰寫的class有需要自己做資源管理(resource management)
  2. 當撰寫以下其中一個成員函數時,需要一併明確定義其他成員函數
    • destructor
    • copy constructor
    • copy assignment operator
    • move constructor (C++11之後, rule of five)
    • move assignment operator (C++11之後, rule of five)

以下為修正過的程式:

#include <iostream>
#include <string>

class ResourceFreeFix
{
    private:
        char *m_str;
    public:
        ResourceFreeFix() = default;
        ResourceFreeFix(const char *pstr) : m_str(new char[128])
        {
            std::strcpy(m_str, pstr);
        }
        // rule of three
        ~ResourceFreeFix()
        {
            delete [] m_str;
        }
        ResourceFreeFix(ResourceFreeFix &Source) : m_str(new char[128])
        {
            strcpy(m_str, Source.m_str);
        }
        void operator = (ResourceFreeFix &Source)
        {
            m_str = Source.m_str;
            Source.m_str = nullptr;
        }
};

int main()
{
    ResourceFreeFix c("resource");
    {
        // d will release resource of c
        ResourceFreeFix d;
        // FIX: assign c to d
        d = c;
    }
    // c will release resource

    return 0;
}

不過有些人的class並不需要使用copy constructor或copy assignment operator.則可以使用兩種方式來解決

  1. 把函數定義在private
  2. 在函數後方加上delete (c++11之後)

Reference

  1. Rule of three (C++ programming)
  2. What is The Rule of Three?

留言

這個網誌中的熱門文章

yocto recipe : (1) 撰寫 recipe

yocto recipe : (2) 撰寫 bbappend

yocto recipe : (3) 使用 External Source 來編譯軟體