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<iostream>
#include<string>
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<iostream>
#include<string.h>
#include<assert.h>
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』