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
- c++中string类的基本功能的实现(1)
- 二叉树的基本功能实现(c++)
- 栈的基本功能实现(C语言)
- C实现数组的基本功能
- 复数类的基本功能实现
- 小游戏:扫雷 (C语言实现扫雷的基本功能)
- 线性表基本功能的c语言实现
- 数据结构C语言版--单链表的基本功能实现
- IOS中数据库的基本功能实现
- Android中一些基本功能的实现
- WINCE实现的基本功能
- wince实现的基本功能
- 串的基本功能实现
- Animation基本功能的实现
- ls基本功能的实现
- Stack类模板的动态数组实现(基本功能)
- Queue类模板的链表实现(基本功能)
- c++实现字符串的基本功能(派生类与继承)
- 回调函数实现冒泡法的多种排序
- 2016百度之星复赛 1003 拍照 扫描线
- C语言常见单链表面试题(1)
- C语言常见单链表面试题(2)
- C语言注释转换为c++的注释
- c++中string类的基本功能的实现(1)
- c/c++单链表面试题—链表带环问题
- c/c++单链表面试题—链表相交问题
- c++实现双向链表的常用功能
- Unity性能优化(CPU)
- 函数模板在c++动态顺序表中的大作用
- 面试题的那些事(1)
- 面试题的那些事(2)—斐波那契数列
- c++智能指针的不断演化