菜鸟笔记
提升您的技术认知

c sring类 浅拷贝&深拷贝© on write-ag真人游戏

c string类的三种实现

浅拷贝

class string
{
public:
    string(const char* pdata)//构造函数
        :_pdata(new char[strlen(pdata)   1])
    {
        strcpy(_pdata, pdata);
    }
    string(const string&s)//拷贝构造
        :_pdata(s._pdata)
    {}
    ~string()//析构函数
    {
        if (null != _pdata)
        {
            delete[]_pdata;
            _pdata = null;
        }
    }
    string &operator=(const string&s)
    {
        //检查自赋值
        if (this != &s)
        {
            char*temp = new char[strlen(s._pdata)   1];
            strcpy(temp, s._pdata);
            delete[]_pdata;
            _pdata = temp;
        }
        return *this;
    }
private:
    char*_pdata;
};
void main()
{
    string s1 ("hello world");
    string s2=s1;
}

当类里面有指针对象时,进行简单赋值的浅拷贝,两个对象指向同一块内存,存在崩溃的问题!这里我们要进行深拷贝。

深拷贝

# define _crt_secure_no_warnings
#include
#include
using namespace std;
class string
{
public:
    string(const char* pdata)//构造函数
        :_pdata(new char[strlen(pdata)   1])
    {
        strcpy(_pdata, pdata);
    }
    string(const string&s)//拷贝构造
        :_pdata(new char[strlen(s._pdata)   1])
    {
        strcpy(_pdata, s._pdata);
    }
    ~string()//析构函数
    {
        if (null != _pdata)
        {
            delete[]_pdata;
            _pdata = null;
        }
    }
    string &operator=(const string&s)
    {
        //检查自赋值
        if (this != &s)
        {
            char*temp = new char[strlen(s._pdata)   1];
            strcpy(temp, s._pdata);
            delete[]_pdata;
            _pdata = temp;
        }
        return *this;
    }
private:
    char*_pdata;
};
//简洁版
class string
{
public:
    string(const char* pdata)
        : _pdata(new char[strlen(pdata)   1])
    {
        strcpy(_pdata, pdata);
    }
    string(const string& s)
        : _pdata(null)
    {
        string temp(s._pdata);
        std::swap(_pdata, temp._pdata);
    }
     string& operator=(const string& s)
         {
             if (this != &s)
             {
                 string temp(s._pdata);
                 std::swap(_pdata, temp._pdata);
             }
             return *this;
         }
     ~string()
     {
         if (null != _pdata)
         {
             delete[] _pdata;
             _pdata = null;
         }
     }
private:
    char* _pdata;
};
void main()
{
    string s1 ("hello world");
    string s2=s1;
}

写时拷贝

#include
#include
#include
namespace cow
{
    class string
    {
    public:
        string(const char* pdata)
            : _pdata(new char[strlen(pdata)   1])
            , _refcount(new int)
        {
            *_refcount = 1;
            strcpy(_pdata, pdata);
        }
        // string s2(s1);
        string(string& s)
            : _pdata(s._pdata)
            , _refcount(s._refcount)
        {
              (*_refcount);
        }
        // s1 = s2;
        string& operator=(string s)
        {
            if (this != &s)
            {
                if (--(*_refcount) == 0)
                {
                    delete[] _pdata;
                    delete _refcount;
                }
                _pdata = s._pdata;
                _refcount = s._refcount;
                  (*_refcount);
            }
            return *this;
        }
        ~string()
        {
            if (--(*_refcount) == 0)
            {
                delete[] _pdata;
                delete _refcount;
            }
        }
        // 返回值  函数名(参数)
        char& operator[](int index)
        {
            // 检测返回
            // *_refcount > 1
            // *_refcount = 1
            if (*_refcount > 1)
            {
                (*_refcount)--;
                string temp(_pdata);
                _pdata = temp._pdata;
                _refcount = temp._refcount;
                (*_refcount)  ;
            }
            return _pdata[index];
        }
        /*const char& operator[](int index)const
        {
            return _pdata[index];
        }*/
    private:
        char* _pdata;
        int* _refcount;
    };
}
void funtest()
{
    cow::string s1("12345");
    cow::string s2("123456789");
    const cow::string s3 = s2;
    s1 = s2;
    s2[0] = '6';
    //std::cout << s3[1];
}
int main()
{
    funtest();
    return 0;
}

string 之间拷贝时不是深拷贝,只拷贝了指针, 也就是共享同一个字符串内容, 只有在内容被修改的时候, 才真正分配了新的内存并 copy 。 比如 s[0]='1' 之类的修改字符串内容的一些write操作, 就会申请新的内容,和之前的共享内存独立开。 所以称之为 『copy-on-write』

网站地图