本文共 5364 字,大约阅读时间需要 17 分钟。
String类:标准库类型string类表示可变长的字符序列,定义在std中,专门用来管理字符串,下面一起看下它的重要考点。
一:浅拷贝:
class String{public: String(const char* pStr = "")//构造函数 :_pStr(new char[strlen(pStr)+1]) { if(0 == *pStr)//字符串为空 { *_pStr = '\0'; } else//字符串不为空 { strcpy(_pStr,pStr); } } String(const String& s)//拷贝构造函数 { _pStr = s._pStr; } String& operator=(String& s)//赋值运算符重载 { if(_pStr != s._pStr)//判断是不是自己给自己赋值 { _pStr = s._pStr; } return *this; } ~String()//析构函数 { if(NULL == _pStr) { return; } else { delete []_pStr; _pStr = NULL; } }private: char* _pStr;};
二:string四个版本的模拟实现:
1. 深拷贝普通版本
class string{public: //构造函数 string(const char* ptr = "") { if (ptr == NULL) { _ptr = new char[1]; *_ptr = '\0'; } _ptr = new char[strlen(ptr) + 1]; strcpy(_ptr, ptr); } //拷贝构造函数 string(const string& s) :_ptr(new char[strlen(s._ptr)+1]) { strcpy(_ptr, s._ptr); } string& operator=(const string& s) { if (this != &s) { char* tmp = new char[strlen(s._ptr) + 1]; strcpy(tmp, s._ptr); delete[] _ptr; _ptr = tmp; } return *this; } ~string() { if (_ptr) { delete[] _ptr; _ptr = NULL; } }private: char* _ptr;};
2. 深拷贝简洁版
版本1:class string{public: //构造函数 string(const char* ptr = "") { if (ptr == NULL) { _ptr = new char[1]; *_ptr = '\0'; } _ptr = new char[strlen(ptr) + 1]; strcpy(_ptr, ptr); } //拷贝构造函数 string(const string& s) :_ptr(new char[strlen(s._ptr)+1]) { strcpy(_ptr, s._ptr); } string& operator=(const string& s) { if (_ptr!=s.ptr) { delete[] _ptr; _ptr = new char[strlen(s._ptr) + 1]; strcpy(_ptr, s._ptr); } return *this; } ~string() { if (_ptr) { delete[] _ptr; _ptr = NULL; } }private: char* _ptr;};
版本2:
class string{public: //构造函数 string(const char* ptr = "") { if (ptr == NULL) { _ptr = new char[1]; *_ptr = '\0'; } _ptr = new char[strlen(ptr) + 1]; strcpy(_ptr, ptr); } //拷贝构造函数 string(const string& s) :_ptr(NULL) { string tmp(s._ptr); std::swap(_ptr, tmp._ptr); } string& operator=(const string& s) { if (_ptr!=s._ptr) { string tmp(s._ptr); std::swap(_ptr,tmp._ptr); } return *this; } ~string() { if (_ptr) { delete[] _ptr; _ptr = NULL; } }private: char* _ptr;};
3. 引用计数
class string{public: //构造函数 string(const char* ptr = "") :_count(new int[0]) , _ptr(new char[strlen(ptr)+1]) { if (ptr == NULL) { _ptr = new char[1]; *_ptr = '\0'; } else strcpy(_ptr, ptr); *_count = 1; } //拷贝构造函数 string(const string& s) :_count(s._count) { _ptr = (char*)(s._ptr); _count = s._count; (*_count)++; } string& operator=(const string& s) { if (_ptr!=s._ptr) { _ptr = s._ptr; _count = s._count; (*_count)++; } return *this; } ~string() { if (_ptr == NULL) return; else { if (--(*_count)==0) { delete[] _ptr; delete[] _count; _ptr = NULL; _count = NULL; } } }private: char* _ptr; int* _count;};
4. 写时拷贝
class string{public: string(const char* ptr="") :_ptr(new char[strlen(ptr)+4+1])//每次多创建4个空间来存放当前地址有几个对象 { if (_ptr == NULL) { (*(int*)_ptr) = 1;//前四个字节拿来计数 _ptr += 4; *_ptr = '\0'; } else { (*(int*)_ptr) = 1; _ptr += 4; strcpy(_ptr, ptr); } } string(const string& s) :_ptr(s._ptr) { ++(*(int*)(_ptr - 4));//向前偏移4个字节将计数加1 } string& operator=(const string& s) { if (_ptr != s._ptr) { if (--(*(int*)(_ptr-4)) == 0) { delete[] _ptr; _ptr = NULL; } _ptr = s._ptr; ++(*(int*)(_ptr - 4)); } } ~string() { if (_ptr == NULL) { return; } else { if (--(*(int*)(_ptr - 4)) == 0) { delete[] (_ptr-4); _ptr = NULL; } } } char& operator[](size_t index)//下标访问操作符重载 { assert(index >= 0 && index < strlen(_ptr)); if ((*(int*)(_ptr - 4))>1)//多个对象指向同一块空间 { char* tmp = new char[strlen(_ptr) + 4 + 1];//新开辟一块空间 tmp += 4;//向后偏移4 strcpy(tmp,_ptr); --(*(int*)(_ptr - 4));//将原来空间的计数器减1 _ptr = tmp;//将当前对象指向临时空间 *((int*)(_ptr - 4)) = 1;//将新空间的计数器变为1 } return _ptr[index]; }private: char* _ptr;};
转载地址:http://wxuoi.baihongyu.com/