美文网首页
Rule of Three/Five/Zero

Rule of Three/Five/Zero

作者: 小雪球的学习笔记 | 来源:发表于2018-06-26 11:52 被阅读0次

    Rule of Three

    If a class requires a user-defined destructor, a user-defined copy constructor, or a user-defined copy assignment operator, it almost certainly requires all three.

    Rule of Five

    Because the presence of a user-defined destructor, copy-constructor, or copy-assignment operator prevents implicit definition of the move constructor and the move assignment operator, any class for which move semantics are desirable, has to declare all five special member functions:

    class string
    {
        char* cstring;
    public:
        //constructor
        string(const char* arg)
         : cstring(new char[std::strlen(arg) + 1 ]) {
             std::strcpy(cstring, arg);
             std::cout<<"constructor called"<<std::endl;
        }
    
        //No.1 destructor
        ~string(){
            delete[] cstring;
             std::cout<<"destructor called"<<std::endl;
        }
    
        //No.2 copy constructor
        string(const string& s)
         : cstring(new char[ s.size() + 1 ]){
             std::strcpy(cstring, s.cstring);
             std::cout<<"copy constructor called"<<std::endl;
        }
    
        //No.3 copy assignment constructor
        //tip 5 need to delete current cstring
        string operator=(const string& s)
        {
            char* tmp_str = new char[s.size() +1];
            std::strcpy(tmp_str, s.cstring);
            delete[] cstring;
            cstring = tmp_str;
             std::cout<<"copy assignment constructor called"<<std::endl;
            return *this;
        }
    
        //No.4 moveconstructor
        //tip 1 move not const parameter
        //tip 2 move constructor no need check self assignment
        string(string&& s) : cstring(s.cstring)
        {
            s.cstring = nullptr;
             std::cout<<"move constructor called"<<std::endl;
        }
    
        //No.5 move assignment constructor
        //tip 4 move assignment need check self assignment
        //tip 5 need to delete current cstring
        string operator=(string&& s)
        {
            if( &s != this) {
                char* tmp_str= s.cstring;
                s.cstring = nullptr;
                delete[] cstring;
                cstring = tmp_str;
            }
            std::cout<<"move assignment constructor called"<<std::endl;
    return *this;
    
        }
    
        //others
        size_t size() const{
            return std::strlen(cstring);
        }
    
    };
    
    #include"string.h"
    #include<iostream>
    // tip 1 utility for std::move
    #include<utility>
    
    int main(){
        const char* a = "hello world";
        string s = string{a};
        string b = string{s};
        string c = string{ std::move(b) };
        string d{a};
        d = c;
        s = std::move(d);
        return 0;
    }
    
    output:
    constructor called
    copy constructor called
    move constructor called
    constructor called
    copy assignment constructor called
    copy constructor called
    destructor called
    move assignment constructor called
    copy constructor called
    destructor called
    destructor called
    destructor called
    destructor called
    destructor called
    
    
    #include"string.h"
    #include<iostream>
    #include<utility>
    
    int main(){
        const char* a = "hello world";
        string b  = string{a};
        std::move(b);
        std::cout<<"move called"<<std::endl;
        string c = string{a};
        c = b;
        return 0;
    }
    output:
    
    constructor called
    move called
    constructor called
    copy assignment constructor called
    copy constructor called
    destructor called
    destructor called
    destructor called
    
    three destructor is due to when assign ment copy . called, b is copied first to argument,
    that is why there is one line copy constructor called after copy assignment constructor called
    

    Rule of zero

    Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership (which follows from the Single Responsibility Principle). Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators.[1]

    相关文章

      网友评论

          本文标题:Rule of Three/Five/Zero

          本文链接:https://www.haomeiwen.com/subject/ropuyftx.html