美文网首页
编写类String的构造函数、析构函数和赋值函数

编写类String的构造函数、析构函数和赋值函数

作者: Magic11 | 来源:发表于2018-03-12 11:20 被阅读0次
    #include <iostream>
    #include <string.h>
    
    using namespace std;
    
    class MyString
    {
    public:
        MyString(const char *str = NULL);
        MyString(const MyString& str);
        MyString& operator=(const MyString& str);
    
        MyString(MyString&& str);
        MyString& operator=(MyString&& str);
    
        ~MyString() {
            delete[] pData;
        }
    
        char* getStr() { return pData; }
    private:
        char* pData;
    };
    
    //注意参数为常量字符串指针
    //当创建一个字符串对象时,此时不是将pData直接指向外部字符串的地址,
    //而是在MyString内部重新创建一个新的字符串,并将pData指向这个新的字符串的地址,
    //所以MyString不会修改外部传入的字符串的内容,这点要注意
    //例如调用MyString("abcdef"), 虽然已经为字符串“abcd”分配了内存,
    //但是在MyString 内部会重新创建一个新的“abcd”
    MyString::MyString(const char *str) {
        cout << "Constructor: MyString is created!"<< endl;
        if (str == NULL) {
            pData = new char[1];
            pData[0] = '\0';
        }
        else
        {
            int len = strlen(str) + 1;
            pData = new char[len];
            strcpy_s(pData, len, str);
        }
    }
    
    MyString::MyString(const MyString& str) {
        cout << "Copy Constructor: MyString is created!" << endl;
        int len = strlen(str.pData); //strlen 碰到'\0'结束,返回的长度长度不包含'\0'
        pData = new char[len + 1];
        strcpy_s(pData, len + 1, str.pData);
    }
    //赋值函数中,上来比较 this == &other 是很必要的,因为防止自复制,这是很危险的,
    //因为下面有delete []m_data,如果提前把m_data给释放了,指针已成野指针,再赋值就错了。
    //返回值必须为引用类型MyString&,否则会调用一次拷贝构造函数
    MyString& MyString::operator=(const MyString& str) {
        cout << "operator= Constructor is Called!" << endl;
        if (this == &str) {
            return *this;
        }
    
        delete[] pData;
    
        int len = strlen(str.pData);
        pData = new char[len + 1];
        strcpy_s(pData, len + 1, str.pData);
    
        return *this;
    }
    
    MyString::MyString(MyString&& other) : pData(other.pData) {
        cout << "Move Copy Constructor: MyString is created!" << endl;
        other.pData = nullptr;
    }
    
    MyString& MyString::operator=(MyString&& other) {
        cout << "Move operator= Constructor is Called!" << endl;
        if (this == &other)
            return *this;
        delete[] pData;
        pData = other.pData;
        other.pData = nullptr;
    }
    
    ostream& operator<<(ostream &output, MyString str) {
        return cout << str.getStr();
    }
    
    MyString getStr() {
        MyString str("Hello");
        return str;
    }
    
    void main() {
    
        MyString str1("hello");             //调用普通构造函数
        MyString str2("world");             //调用普通构造函数
        
        MyString str3(str1);                //调用拷贝构造函数
    
        str3 = str2;                        //调用赋值函数
    
        MyString str4 = getStr();
        
        MyString str5;
        str5 = getStr();
    
        getchar();
    }
    

    运行结果如下:

    Constructor: MyString is created!
    
    Constructor: MyString is created!
    
    Copy Constructor: MyString is created!
    
    operator= Constructor is Called!
    
    Constructor: MyString is created!
    Move Copy Constructor: MyString is created!
    
    Constructor: MyString is created!
    Constructor: MyString is created!
    Move Copy Constructor: MyString is created!
    Move operator= Constructor is Called!
    

    这里的细节可以参考一下陈硕的

    C++面试中string类的一种正确简明的写法

    https://www.cnblogs.com/Solstice/p/3362913.html
    https://github.com/chenshuo/recipes/blob/master/string/StringTrivial.h

    相关文章

      网友评论

          本文标题:编写类String的构造函数、析构函数和赋值函数

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