#include <iostream>
#include <string.h>
using namespace std;
class String;
class StringRep {
friend class String;
friend ostream& operator<<(ostream& os, const String& s);
StringRep(const char* s); // StringRep constructor
~StringRep(); // StringRep destructor
int count;
char *rep;
};
// StringRep constructor
StringRep::StringRep(const char* s):count(1) {
if(NULL == s) {
rep = new char[1];
*rep= '\0';
}
else {
rep = new char[strlen(s)+1];
strcpy(rep, s);
}
}
// StringRep destructor
StringRep::~StringRep() {
delete[] rep;
rep = NULL;
}
class String {
public:
String(); // default constructor
String(const char* s); // constructor
String(const String& s); // copy constructor
String& operator=(const String& s); // copy assignment
~String(); // destructor
public:
bool empty() {
return this->rep->rep[0] == '\0'? true:false;
}
int length() {
return strlen(this->rep->rep);
}
int get_rep_count() {
return this->rep->count;
}
public:
//Copy-On-Write
String& operator+=(const String& s); // operator+=
String operator+(const String& s); // operator+
char& operator[](size_t index); // operator[]
const char& operator[](size_t index)const ; // const operator[]
public:
friend ostream& operator<<(ostream &os, const String& s); // operator<<
private:
StringRep* rep; // pimpl
};
// default constructor
String::String():rep(new StringRep(NULL)) {
}
// constructor
String::String(const char* s):rep(new StringRep(s)) {
}
// copy constructor
String::String(const String& s):rep(s.rep) {
//1.地址赋值2.引用计数++
++rep->count;
}
// copy assignment
String& String::operator=(const String& s) {
//1.判断是否为同一个字符串地址
if(this->rep == s.rep) {
return *this;
}
//2.原始引用地址的引用计数--
if(0 == --this->rep->count) {
delete this->rep;
}
//3.更新地址
this->rep = s.rep;
//4.新地址?引用计数++
++this->rep->count;
return *this;
}
// destructor
String::~String() {
//引用计数减为0的时候,才会销毁原始地址
if(0 == --this->rep->count) {
delete this->rep;
}
}
// operator<<
ostream& operator<<(ostream &os, const String& s) {
os << s.rep->rep ;
return os;
}
//Copy-On-Write
//operator+=
String& String::operator+=(const String& s) {
//1.原始地址引用计数--,清空地址
if(0 == --this->rep->count) {
//注意这种情况: str+=str;
if(this != &s) {
//if(this->rep != s.rep) {
delete this->rep;
}
}
//2.s.rep->rep 为空
if(NULL == s.rep->rep) {
this->rep = new StringRep(this->rep->rep);
return *this;
}
//3.this->rep->rep 为空
if(NULL == this->rep->rep) {
this->rep = new StringRep(s.rep->rep);
return *this;
}
//4.申请空间构造字符
char *temp = new char[strlen(this->rep->rep)+ strlen(s.rep->rep)+1];
strcpy(temp, this->rep->rep);
strcat(temp, s.rep->rep);
//上面str+=str;这种情况处理完成,如果此时引用计数为0,则销毁,防止内存泄漏
//if(0 == this->rep->count && this->rep == s.rep) {
if(0 == this->rep->count && this == &s) {
delete this->rep;
}
//5.为委托指针赋值
this->rep = new StringRep(temp);
//6.删除申请空间
delete []temp;
temp = NULL;
//7.返回新对象
return *this;
}
//Copy-On-Write
String String::operator+(const String& s) // operator+
{
return String(*this) += s;
}
//Copy-On-Write
char& String::operator[](size_t index) // operator[]
{
//如果引用数目>1,拷贝一份
if(this->rep->count > 1) {
--this->rep->count;
this->rep = new StringRep(this->rep->rep);
}
//否则现在就是1份,直接使用即可
if(index < length()) {
return this->rep->rep[index];
}
}
const char& String::operator[](size_t index) const // const operator[]
{
if(index < strlen(this->rep->rep)) {
return this->rep->rep[index];
}
}
int main() {
String str1 = "hello";
cout << "str1: " << str1 << " str1:count " << str1.get_rep_count() << endl;
cout << "------------------------------" << endl;
String str2 = str1;
cout << "str1: " << str1 << " str1:count " << str1.get_rep_count() << endl;
cout << "str2: " << str2 << " str2:count " << str2.get_rep_count() << endl;
cout << "------------------------------" << endl;
str2 = "hello";
//str2不引用str1的rep,所以count会--
cout << "str1: " << str1 << " str1:count " << str1.get_rep_count() << endl;
cout << "str2: " << str2 << " str2:count " << str2.get_rep_count() << endl;
cout << "------------------------------" << endl;
String str3=str2;
String str4=str2;
//str1是原始位置,str3,str4都是引用str2位置
cout << "str1: " << str1 << " str1:count " << str1.get_rep_count() << endl;
cout << "str2: " << str2 << " str2:count " << str2.get_rep_count() << endl;
cout << "str3: " << str3 << " str3:count " << str3.get_rep_count() << endl;
cout << "str4: " << str4 << " str4:count " << str4.get_rep_count() << endl;
cout << "------------------------------" << endl;
/*str2 += str2;
//str2不在使用原来位置,引用计数--,str4,str3
cout << "str1: " << str1 << " str1:count " << str1.get_rep_count() << endl;
cout << "str2: " << str2 << " str2:count " << str2.get_rep_count() << endl;
cout << "str3: " << str3 << " str3:count " << str3.get_rep_count() << endl;
cout << "str4: " << str4 << " str4:count " << str4.get_rep_count() << endl;
cout << "------------------------------" << endl;*/
str2 += str3;
cout << "str1: " << str1 << " str1:count " << str1.get_rep_count() << endl;
cout << "str2: " << str2 << " str2:count " << str2.get_rep_count() << endl;
cout << "str3: " << str3 << " str3:count " << str3.get_rep_count() << endl;
cout << "str4: " << str4 << " str4:count " << str4.get_rep_count() << endl;
cout << "------------------------------" << endl;
str4=str2;
String str5;
String temp("++++");
cout << "str5: " << str5<< " str5:count " << str5.get_rep_count() << endl;
str5 = str2 + temp;
cout << "str1: " << str1 << " str1:count " << str1.get_rep_count() << endl;
cout << "str2: " << str2 << " str2:count " << str2.get_rep_count() << endl;
cout << "str3: " << str3 << " str3:count " << str3.get_rep_count() << endl;
cout << "str4: " << str4 << " str4:count " << str4.get_rep_count() << endl;
cout << "str5: " << str5<< " str5:count " << str5.get_rep_count() << endl;
cout << "------------------------------" << endl;
char ch = str2[3];
cout << "index_char[3]: " << ch << endl;
cout << "str1: " << str1 << " str1:count " << str1.get_rep_count() << endl;
cout << "str2: " << str2 << " str2:count " << str2.get_rep_count() << endl;
cout << "str3: " << str3 << " str3:count " << str3.get_rep_count() << endl;
cout << "str4: " << str4 << " str4:count " << str4.get_rep_count() << endl;
cout << "str5: " << str5<< " str5:count " << str5.get_rep_count() << endl;
cout << "------------------------------" << endl;
const char ch2 = str2[4];
cout << "index_char[2]: " << ch2 << endl;
cout << "str1: " << str1 << " str1:count " << str1.get_rep_count() << endl;
cout << "str2: " << str2 << " str2:count " << str2.get_rep_count() << endl;
cout << "str3: " << str3 << " str3:count " << str3.get_rep_count() << endl;
cout << "str4: " << str4 << " str4:count " << str4.get_rep_count() << endl;
cout << "str5: " << str5<< " str5:count " << str5.get_rep_count() << endl;
cout << "------------------------------" << endl;
return 0;
}
本文介绍了一种基于C++的字符串池化技术实现方法,通过Copy-On-Write(写时复制)机制来提高字符串操作的效率并减少内存消耗。文章详细解释了字符串类的设计,包括构造函数、析构函数、赋值运算符等,并展示了如何利用这些机制来避免不必要的字符串复制。
&spm=1001.2101.3001.5002&articleId=72287258&d=1&t=3&u=1cd390b3205f4526a4f6529cffe091e2)
367

被折叠的 条评论
为什么被折叠?



