c++中string类的基本功能的实现(1)

来源:互联网 发布:帝国cms支持视频 编辑:程序博客网 时间:2024/06/10 21:12

1、传统的实现string类的方法

优点:程序简单易懂

缺点:

1)在实现其拷贝构造和赋值的操作时多次的调用new动态的开辟空间,因此也需要多次的通过delete来释放空间。如果处理不当还容易造成内存泄漏。

2)程序的一致性比较差

#include <iostream>#include <string>using namespace std;class String {public:// 构造函数String(char *str = ""):_str(new char [strlen(str)+1]){if (_str != NULL){strcpy(_str, str);}}//拷贝构造String(const String& str):_str(new char[strlen(str._str) + 1]){if (_str != NULL){strcpy(_str, str._str);}}//赋值String& operator = (const String& str){if (this != &str)//自赋值问题{delete[]_str;//释放之前开辟的空间_str = new char[strlen(str._str) + 1];//开辟新的空间strcpy(_str, str._str);//拷贝}return *this;}//析构函数~String(){delete [] _str;}private:char * _str;};

2、现代的实现string类的方法写实

拷贝构造实现思路:

a)创建一个临时对象,并通过cconst String._str来构造。

b)构造完成之后将临时对象的_str和this._str进行交换进而使得对象的内容交换来完成拷贝构造

赋值实现思路:

通过参数的值传递来构造对象,并将对象的内容交换

优点:

1)程序的一致性比较好

2)只是在构造函数中出现了开辟空间的new,只在析构函数中出现了delete结构清晰,不容易造成内存泄漏

class String {public:// 构造函数String(char *str = ""):_str(new char [strlen(str)+1]){if (_str != NULL){strcpy(_str, str);}}//拷贝构造String(const String& str):_str(NULL)//防止其指向一份不合法的空间{String tmp(str._str);swap(_str, tmp._str);}//赋值String& operator =(String str){swap(_str, str._str);return *this;}//析构函数~String(){delete [] _str;}private:char * _str;};


3、写实函数提高string类的效率

在以上的两种string类的实现方法中,都存在一个效率的问题。有的时候字符串比较长,而且对象建立之后也不一定更改。但是以上两种方法无论何时都需要构建,其效率比较低而且会带来内存的浪费。

我们可以通过让所有指向相同字符串内容的对象指向同一份空间,通过计数器来记录对象的个数,避免析构出现错误。

所以可以通过在开辟对象的时候多开辟4个字节的空间,来存放计数器。如果修改的时候再开辟空间。

#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include <string>using namespace std;class String {public://构造函数String(char *str=""):_Pstr(FindStartRef(new char[strlen(str)+1+sizeof(int)])){*Count(_Pstr) = 1;//计数器strcpy(_Pstr, str);//将字符串拷贝}//拷贝构造函数//如果不更改对象的内容则让多个对象的字符指针指向同一份空间String(const String& s){_Pstr = s._Pstr;(*Count(_Pstr))++;//计数器加1}//赋值语句//如果不更改对象的内容则让多个对象的字符指针指向同一份空间String& operator =(const String& s){if (this != &s)//避免自赋值{if (--*(Count(_Pstr)) == 0){delete[]FindDel(_Pstr);}//只有一个对象使用的一份空间则释放else{_Pstr = s._Pstr;(*Count(_Pstr))++;}}return *this;}//析构函数~String(){if (--*(Count(_Pstr)) == 0){delete[]FindDel(_Pstr);}}public://找到开辟空间时的存放字符串的首地址char * FindStartRef(char* str){return (str + 4);}//找到释放空间时的首地址char * FindDel(char* del){return (del - 4);}//找到计数器的首地址int *Count(char* str){return (int *)(str - 4);}public://修改写实对象的内容函数char & operator[](int index){if (--*(Count(_Pstr)) != 0){char * tmp = _Pstr;_Pstr = FindStartRef(new char[strlen(_Pstr) + 1 + sizeof(int)]);*Count(_Pstr) = 1;//计数器置1strcpy(_Pstr, tmp);}//如果该对象和其他对象公用一份空间else{//单独使用一份空间可以随意更改}return _Pstr[index];}private:char * _Pstr;};


0 0
原创粉丝点击