c++11的移動拷貝構造函數和移動賦值

my_string(const char* str)
{
    int len = strlen(str);
    len_ = len;
    buffer_ = new char[len_ + 1];
    memset(buffer_, 0, len_ + 1);

    memcpy(buffer_, str, len_);
}

~my_string()
{
    if (buffer_ != nullptr){
        delete[]buffer_;
        buffer_ = nullptr;
    }
}

my_string()
{
    buffer_ = new char[len_];
    buffer_[0] = 0;
}

//默認的構造函數淺拷貝(不用delete的原因是object ob(ob1);一定分配好)
my_string(const my_string& str)
{
    len_ = str.get_len();
    
    if (len_ ==0){
        return;
    }

    //語法沒錯,可能編譯會拋
    buffer_ = new char[len_ + 1];
    memset(buffer_, 0, len_ + 1);
    memcpy(buffer_, str.data(), len_);
}

//賦值構造函數
my_string& operator=(const my_string& str)
{
    if (this !=&str){
        int len = str.get_len();
        if (this->buffer_ != nullptr) {
            delete[] buffer_;
            buffer_ = nullptr;
        }

        len_ = len;
        this->buffer_ = new char[len_ + 1];
        memset(buffer_, 0, len_ + 1);
        memcpy(buffer_, str.data(), len_);
    }

    return *this;

}

my_string( my_string&& str) noexcept
{
    this->buffer_ = str.data();
    this->len_ = str.get_len();
    str.set_len(0);
    str.ret_null();
}

    my_string& operator=(my_string&& str)noexcept {
        if (this != &str){
            if (buffer_ != nullptr){
                delete[] buffer_;
                buffer_ = nullptr;
            }
    
            buffer_ = str.data();
            len_ = str.get_len();
            str.ret_null();
            str.set_len(0);
        }

        return *this;
    }

    std::size_t get_len()const {
        return len_;
    }
    
    char* data() const{
        return buffer_;
    }

    void ret_null() {
        buffer_ = nullptr;
    }
    void set_len(int len) {
        len_ = len;
    }

#include <string>
#include <type_traits> 

//const my_string getPerson()
//{
//    my_string person("person in func");
//    return std::move(person);
//}

//不能返回局部變量的引用
//const my_string& getPerson()
//{
//    my_string person("person in func");
//    return person;
//}

//所以臨時對象一定要std::move
const my_string getPerson()
{
    my_string person("person in func");
    return std::move(person);
}

int main()
{

   //std::vector<my_string> src{ "foo", "bar", "baz" };
    //std::vector<my_string> dest(src.size());

    ////move_backward會執行移動賦值函數
    //std::move_backward(src.begin(),src.end(),dest.end());

 

    std::string str = "1234567";
    std::string str1 = "7895624";
    my_string mystr(str.c_str());
    my_string mystr2(str1.c_str());
    ////臨時對象
    my_string mystr33(getPerson());
    ////一定賦值
    mystr2 = std::move(mystr);

    //臨時對象會執行移動構造函數
    //my_string mystr44(std::move(my_string("123")));
    //forward也會講一個左值變右值
    //my_string mystr55(std::forward<my_string>(my_string("22222")));
    //注意不會執行,移動構造函數
    //它是一個左值拷貝
    //my_string mystr55(my_string("123"));
    return 0;
}

總結:

1:std::move函數就是左值轉右值(若右值的話,就不想轉)

2:std::forward函數就是左值轉右值,右值的話就不轉

3:  move_backward會執行移動賦值函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章