【String】引用计数实现String

来源:互联网 发布:淘宝修真记下载 编辑:程序博客网 时间:2024/05/24 01:41

String.h

#ifndef STRING_H#define STRING_H#define _CRT_SECURE_NO_WARNINGS#include<iostream>//Stringclass String{public:String(const char* str = NULL);//constructorString(const String& rhs);//copy constructorString& operator=(const String& rhs);//copy assignment~String();//destructorString& operator+=(const String& rhs);//operator+=String operator+(const String& rhs);//operator+bool operator==(const String& rhs);//operator==char& operator[](size_t index); //operator[]const char& operator[](size_t index)const;//const operator[]void copy(const String& rhs);//copyint compare(const String& rhs);//compareString substr(size_t pos, size_t len);//substringString& insert(size_t pos, String& rhs);//insertString& erase(size_t pos, size_t len);//erasebool empty();//whether String is empty or notsize_t length();//get String lengthsize_t get_ref_count();//get ref_countfriend std::istream& operator>>(std::istream& is, const String& str);//operator>>friend std::ostream& operator<<(std::ostream& os, const String& str);//operator<<private:struct StringValue{int ref_count;char* data;StringValue(const char* str);//StringValue constructor~StringValue();//StringValue destructor};StringValue* value;};//StringValue constructorString::StringValue::StringValue(const char* str) :ref_count(1){if (str == NULL){data = new char[1];data[0] = '\0';}else{data = new char[strlen(str) + 1];strcpy(data, str);}}//StringValue destructorString::StringValue::~StringValue(){delete[] data;data = NULL;}//constructorString::String(const char* str) :value(new StringValue(str)){}//copy constructorString::String(const String& rhs):value(rhs.value){++value->ref_count;}//copy assignmentString& String::operator=(const String& rhs){if (this->value == rhs.value)return *this;if (--this->value->ref_count == 0)delete this->value;this->value = rhs.value;++this->value->ref_count;return *this;}//destructorString::~String(){if (--this->value->ref_count == 0)delete this->value;}//operator+=String& String::operator+=(const String& rhs){if (--this->value->ref_count == 0)delete this->value;if (rhs.value->data == NULL){this->value = new StringValue(this->value->data);return *this;}if (this->value->data == NULL){this->value = new StringValue(rhs.value->data);return *this;}char* temp = new char[strlen(this->value->data) + strlen(rhs.value->data) + 1];strcpy(temp, this->value->data);strcat(temp, rhs.value->data);this->value = new StringValue(temp);return *this;}//operator+String String::operator+(const String& rhs){return String(*this) += rhs;}//operator==bool String::operator==(const String& rhs){return compare(rhs) == 0 ? true : false;}//operator[]char& String::operator[](size_t index){if (this->value->ref_count > 1){--this->value->ref_count;this->value = new StringValue(this->value->data);}if (index < strlen(this->value->data))return this->value->data[index];}//const operator[]const char& String::operator[](size_t index)const{if (index < strlen(this->value->data))return this->value->data[index];}//copyvoid String::copy(const String& rhs){operator=(rhs);}//compareint String::compare(const String& rhs){for (int i = 0; i < strlen(this->value->data) && i < strlen(rhs.value->data); i++){if (this->value->data[i] != rhs.value->data[i]){return this->value->data[i] - rhs.value->data[i];}}return strlen(this->value->data) - strlen(rhs.value->data);}//substringString String::substr(size_t pos, size_t len){if (pos>length()-len){std::cout << "pos+len>String length" << std::endl;exit(1);}char* temp = new char[len + 1];int i;for (i = 0; i < len; i++){temp[i] = this->value->data[pos + i];}temp[i] = '\0';return String(temp);}//insertString& String::insert(size_t pos, String& rhs){if (pos>this->length()){std::cout << "pos>String length" << std::endl;exit(1);}if (--this->value->ref_count == 0)delete this->value;char* temp = new char[this->length() + rhs.length() + 1];int i;for (i = 0; i < pos; i++){temp[i] = this->value->data[i];}for (; i < pos + rhs.length(); i++){temp[i] = rhs.value->data[i - pos];}for (; i < this->length() + rhs.length(); i++){temp[i] = this->value->data[i - rhs.length()];}temp[i] = '\0';this->value = new StringValue(temp);return *this;}//eraseString& String::erase(size_t pos, size_t len){if (pos>this->length()-len){std::cout << "pos+len>String length" << std::endl;exit(1);}if (--this->value->ref_count == 0)delete this->value;char* temp = new char[this->length() - len + 1];int i;for (i = 0; i < pos; i++){temp[i] = this->value->data[i];}for (; i < this->length() - len + 1; i++){temp[i] = this->value->data[i + len];}temp[i] = '\0';this->value = new StringValue(temp);return *this;}//whether String is empty or notbool String::empty(){return this->value->data[0] == '\0' ? true : false;}//get String lengthsize_t String::length(){return strlen(this->value->data);}//get ref_countsize_t String::get_ref_count(){return this->value->ref_count;}//operator>>std::istream& operator>>(std::istream& is, const String& str){is >> str.value->data;return is;}//operator<<std::ostream& operator<<(std::ostream& os, const String& str){os << str.value->data;return os;}#endif
main.cpp

#include"String.h"  using namespace std;int main(){String str1("hello world");//call constructorString str2 = str1;//call copy constructorString str3;//call constructorcout << boolalpha << str1.empty() << endl;//falsecout << boolalpha << str2.empty() << endl;//falsecout << boolalpha << str3.empty() << endl;//truestr3 = str2;//call copy assignmentcout << "str1 reference count:" << str1.get_ref_count() << endl; // 3  cout << "str2 reference count:" << str2.get_ref_count() << endl; // 3  cout << "str3 reference count:" << str3.get_ref_count() << endl; // 3  str1[0] = 'H';//call operator[]cout << str1 << endl; //"Hello world"  cout << str2 << endl;//"hello world"  cout << str3 << endl;//"hello world"   cout << "str1 reference count:" << str1.get_ref_count() << endl;//1  cout << "str2 reference count:" << str2.get_ref_count() << endl;//2  cout << "str3 reference count:" << str3.get_ref_count() << endl;//2  String str4("hello");//call constructorString str5 = str4;//call copy constructor String str6 = " world";//call constructor str5 = str5 + str6;//call operator+,copy constructorcout << str4 << endl; //"hello"  cout << str5 << endl; //"hello world"  cout << str6 << endl; //" world"  cout << "str4 reference count:" << str4.get_ref_count() << endl;//1  cout << "str5 reference count:" << str5.get_ref_count() << endl;//1  cout << "str6 reference count:" << str6.get_ref_count() << endl;//1  String str7 = str5;//call copy constructor String str8;//call constructorstr8 = str7;////call copy constructor cout << str7 << endl; //"hello world"  cout << "str5 reference count:" << str5.get_ref_count() << endl;//3  cout << "str7 reference count:" << str7.get_ref_count() << endl;//3  cout << "str8 reference count:" << str8.get_ref_count() << endl;//3  str5 += str6;//call operator+=cout << str5 << endl; //"hello world world"  cout << str6 << endl; //" world"  cout << str7 << endl; //"hello world"  cout << str8 << endl; //"hello world"  cout << "str5 reference count:" << str5.get_ref_count() << endl; //1  cout << "str6 reference count:" << str6.get_ref_count() << endl;//1  cout << "str7 reference count:" << str7.get_ref_count() << endl;//2  cout << "str8 reference count:" << str8.get_ref_count() << endl;//2  String str9; //call constructorstr9 = str8.substr(1, 3);cout << str9 << endl;//"ell"cout << "str8 reference count:" << str8.get_ref_count() << endl;//2  cout << "str9 reference count:" << str9.get_ref_count() << endl;//1  cout << "str9 length:" << str9.length() << endl;//3String str10;str10.copy(str9);cout << str9 << endl;//"ell"cout << str10 << endl;//"ell"cout << "str9 reference count:" << str9.get_ref_count() << endl;//2  cout << "str10 reference count:" << str10.get_ref_count() << endl;//2if (str9.compare(str10) == 0)cout << "equal" << endl; //equalelsecout << " not equal" << endl;str10.insert(2, String("abc"));cout << str9 << endl;//"ell"cout << str10 << endl;//"elabcl"cout << "str9 reference count:" << str9.get_ref_count() << endl;//1  cout << "str10 reference count:" << str10.get_ref_count() << endl;//1String str11 = str10;cout << str10 << endl;//"elabcl"cout << str11 << endl;//"elabcl"cout << "str10 reference count:" << str10.get_ref_count() << endl;//2 cout << "str11 reference count:" << str11.get_ref_count() << endl;//2str11.erase(2, 2);cout << str10 << endl;//"elabcl"cout << str11 << endl;//"elcl"cout << "str10 reference count:" << str10.get_ref_count() << endl;//1  cout << "str11 reference count:" << str11.get_ref_count() << endl;//1return 0;}

0 0