PIMPL实现String(pointer to implementation)

来源:互联网 发布:nginx后端服务器监控 编辑:程序博客网 时间:2024/06/11 21:47




#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 destructorint count;char *rep;};// StringRep constructorStringRep::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 destructorStringRep::~StringRep() {delete[] rep;rep = NULL;}class String {public:String();  // default constructorString(const char* s);  // constructorString(const String& s); // copy constructorString& operator=(const String& s);  // copy assignment~String();  // destructorpublic: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-WriteString& 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 constructorString::String():rep(new StringRep(NULL)) {}// constructorString::String(const char* s):rep(new StringRep(s)) {}// copy constructorString::String(const String& s):rep(s.rep) {//1.地址赋值2.引用计数++++rep->count;}// copy assignmentString& 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-WriteString String::operator+(const String& s)  // operator+{return String(*this) += s;}//Copy-On-Writechar& 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,str3cout << "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;}




原创粉丝点击