C++string的模拟实现(上篇)
创始人
2024-05-22 12:58:39
0

目录

一.命名空间的封装与交换函数模板

1.命名空间的封装与类的定义

2.交换函数模板 

二.string类的四个重要默认成员函数

1.构造函数的类外定义:

2.析构函数在类外的定义

3.拷贝构造函数在类外的定义

4.赋值运算符重载在类外的定义 

5.关于两个string对象的内容交换问题

三.string类的迭代器 

四.string类的[]成员重载


一.命名空间的封装与交换函数模板

1.命名空间的封装与类的定义

模拟实现的string类最好用一个命名空间封装起来避免发生命名冲突。

命名空间定义:

namespace mystring
{//.....
}

类的定义(为了方便整理和维护,成员方法的声明和定义分离):

(本期不含增删查改的接口)


namespace mystring
{class string{public:typedef char * iterator;                  //宏定义string类的迭代器typedef const char* const_iterator;string(const char* nstr);                  //类中四个重要的默认成员函数string(const string& nstr);~string();string& operator=(string nstr);void copyswap(string &nstr);               //复用交换函数的接口iterator begin();                          //string类用于获取迭代器的接口iterator end();const_iterator begin()const;const_iterator end()const;const char * C_str()const;                 //用于返回C类型字符串的函数char & operator[](int pos);                //用于返回pos下标字符的引用的[]重载const char & operator[](int pos) const;     size_t size() const;                       //获取有效字符个数size和容量的接口size_t capacity() const;private:char * _str;size_t _size;size_t _capacity;};}

2.交换函数模板 

template 
void myswap (T& e1 , T&e2)
{T tem = e1;e1 = e2;e2 =tem;
}

该模板可以根据传入的实参类型生成用于交换对应类型数据的函数实例。

二.string类的四个重要默认成员函数

1.构造函数的类外定义:

类外声明方法时注意表明方法所在命名空间和类域

mystring::string::string(const char* nstr = "") :_size(strlen(nstr))                            ,_capacity (_size)
{                          _str = new char[_capacity+1];                strcpy(_str,nstr);
}
  • 设计缺省参数是为了保证类的构造函数可以被无参调用,(形参缺省值可用于构造空字符串)(会完成'\0'的拷贝)(注意参数缺省值只能写在函数的声明和定义其中一个之中)
  • strlen函数中有关于空指针的断言,所以构造函数中无须进行空指针断言
  •  +1是为了保存'\0'(不计入容量和有效字符),同时保证_str不为空指针(对象只要创建出来就一定要维护一块堆空间,防止析构的时候程序崩溃)

2.析构函数在类外的定义

mystring::string::~string()
{if(_str){delete[] _str;      释放堆区空间_str=nullptr;}_size=0;_capacity=0;
}

3.拷贝构造函数在类外的定义

    mystring::string::string(const string& nstr):_size(nstr._size),_capacity(nstr._capacity){_str = new char[_capacity+1];             strcpy(_str,nstr._str);}

这是一种非复用的写法,现代STL中比较喜欢使用复用的写法,拷贝构造函数可以通过复用构造函数来实现,从而使代码更加简洁:

现在类中定义一个成员交换函数(该函数通过复用swap函数实现):

    //template //void myswap (T& e1 , T&e2)//{//   T tem = e1;//   e1 = e2;//   e2 =tem;//}void mystring::string::copyswap(string & nstr){myswap(_str,nstr._str);myswap(_size,nstr._size);myswap(_capacity,nstr._capacity);}

调用该成员函数可以将两个string对象的各个成员变量进行交换

复用构造函数实现拷贝构造函数:

    mystring::string::string(const string& nstr)     //复用构造函数完成拷贝构造:_str (nullptr)                                  //防止tem中_str作为野指针被释放,_size(0),_capacity(0){string tem(nstr._str);                       //拷贝构造拷贝的是不含'\0'的有效字符this->copyswap(tem);                         //为了方便阅读加上this指针}

该实现方法的思想是通过形参对象中的字符串构造tem临时对象,再将tem对象中的内容通过交换函数置换到被构造的对象中去。

tem在函数体执行完后会自动调用自身的析构函数并销毁。

4.赋值运算符重载在类外的定义 

   string& mystring::string::operator=(const string& nstr){if(this != &nstr)                           //判断重载操作数是否为同一个对象{char * tem = new char[nstr._capacity+1];  strcpy(tem,nstr._str);delete[] _str;                           //释放原来的堆区空间_str = tem;_size = nstr._size;_capacity = nstr._capacity;}return *this;}
  • 注意不能直接用_str去接收新申请的堆区空间地址(因为new可能会失败)
  • 注意返回对象本身的引用*this(使=重载可以满足连等赋值)

赋值运算符重载也可以通过复用拷贝构造来实现:

    string& mystring::string::operator=(string nstr)     {copyswap(nstr);return (*this);}
  • 复用拷贝构造实现赋值运算符重载的思路:

5.关于两个string对象的内容交换问题

  • STL的标准库中string类中有成员交换函数swap(相当于本篇模拟实现中的copyswap成员函数),使用成员函数完成两个string对象的内容交换效率远高于直接使用全局swap函数(相当于本篇模拟实现中的myswap函数)完成两个string对象的内容交换
  • 直接调用全局交换函数交换两个string对象会额外调用对象的拷贝构造函数和赋值运算符重载从而增加性能消耗(new申请空间的性能消耗是很大的)

比如:

using mystring::string;
using mystring::myswap;int main()
{string a("hello");string b("world");myswap(a,b);    交换方式一(直接调用全局交换函数)a.copyswap(b);  交换方式二(调用成员交换函数)return 0;}

两种对象交换的方式差异图解:

三.string类的迭代器 

string类的迭代器可以typedef为字符指针

    mystring::string::iterator mystring::string:: begin(){return _str;}mystring::string::iterator mystring::string::end(){return _str+_size; }mystring::string::const_iterator mystring::string::begin()const{return _str;}mystring::string::const_iterator mystring::string::end()const{return _str+_size;}

四.string类的[]成员重载

string类的[]成员重载用于返回字符串中指定下标的字符的引用

    char &  mystring::string::operator[](int pos){assert(pos<_size);return _str[pos];}const char &  mystring::string::operator[](int pos) const{assert(pos<_size);return _str[pos];}
  • const修饰的重载成员是供const修饰的string对象调用的

完整代码:

#include
#include
#include 
//只要不涉及寻址,一定要注意编译器的顺序编译机制namespace mystring
{class string{public:typedef char * iterator; typedef const char* const_iterator;string(const char* nstr);                  //类中四个重要的默认成员函数string(const string& nstr);~string();string& operator=(string nstr);void copyswap(string &nstr);               //复用交换函数的接口iterator begin();                          //string类用于获取迭代器的接口iterator end();const_iterator begin()const;const_iterator end()const;const char * C_str()const;                 //用于返回C类型字符串的函数char & operator[](int pos);                //用于返回pos下标字符的引用的[]重载const char & operator[](int pos) const;     size_t size() const;                       //获取有效字符个数size和容量的接口size_t capacity() const;private:char * _str;size_t _size;size_t _capacity;};template void myswap (T& e1 , T&e2){T tem = e1;e1 = e2;e2 =tem;}void mystring::string::copyswap(string & nstr){myswap(_str,nstr._str);myswap(_size,nstr._size);myswap(_capacity,nstr._capacity);}const char * mystring::string::C_str() const{return _str;}mystring::string::string(const char* nstr = "")  //缺省值用于构造空字符串(会完成'\0'的拷贝)(注意缺省参数只能写在声明和定义其中一个之中):_size(strlen(nstr))                             //strlen函数中有关于空指针的断言,所以构造函数中无须进行空指针判断,_capacity (_size){                          _str = new char[_capacity+1];                // +1是为了保存'\0'(不计入容量和有效字符),同时保证_str不为空指针(对象只要创建出来就一定维护一块堆空间)strcpy(_str,nstr);}// mystring::string::string(const string& nstr)  //非复用式写法// :_size(nstr._size)// ,_capacity(nstr._capacity)// {//     _str = new char[_capacity+1];             // +1是为了保存'\0'(不计入容量和有效字符),同时保证_str不为空指针//     strcpy(_str,nstr._str);// }mystring::string::string(const string& nstr)     //复用构造函数完成拷贝构造:_str (nullptr)                                  //防止tem中_str作为野指针被释放,_size(0),_capacity(0){string tem(nstr._str);                       //拷贝的是不含'\0'的有效字符this->copyswap(tem);                         //为了方便阅读加上this指针}// string& mystring::string::operator=(const string& nstr)// {//     if(this != &nstr)                             //判断重载操作数是否为同一个对象//     {//         char * tem = new char[nstr._capacity+1];  // +1是为了保存'\0'(不计入容量和有效字符)//         strcpy(tem,nstr._str);//         delete[] _str;//         _str = tem;//         _size = nstr._size;//         _capacity = nstr._capacity;//     }//     return *this;// }string& mystring::string::operator=(string nstr)     //与直接交换对象作对比{copyswap(nstr);return (*this);}mystring::string::~string(){if(_str){delete[] _str;_str=nullptr;}_size=0;_capacity=0;}mystring::string::iterator mystring::string:: begin(){return _str;}mystring::string::iterator mystring::string::end(){return _str+_size; }mystring::string::const_iterator mystring::string::begin()const{return _str;}mystring::string::const_iterator mystring::string::end()const{return _str+_size;}char &  mystring::string::operator[](int pos){assert(pos<_size);return _str[pos];}const char &  mystring::string::operator[](int pos) const{assert(pos<_size);return _str[pos];}size_t mystring::string::size() const{return _size;}size_t mystring::string::capacity() const{return _size;}

相关内容

热门资讯

推荐为英语作文【实用6篇】 推荐为英语作文 篇一:The Benefits of Learning a Second Langu...
距离产生美英语作文【优秀3篇... 距离产生美英语作文 篇一The Beauty of DistanceDistance, whethe...
英语报告类作文格式范文(精简... 英语报告类作文格式范文 篇一Title: The Importance of Environment...
描写金鱼的英语作文【优秀6篇... 描写金鱼的英语作文 篇一Title: The Graceful Beauty of Goldfish...
我的梦想英语作文 我的梦想英语作文(精选25篇)  在平时的学习、工作或生活中,大家一定都接触过作文吧,根据写作命题的...
我的爱人的英语作文【优选3篇... 我的爱人的英语作文 篇一My Beloved PartnerLove is a beautiful ...
优秀英语作文范文(经典6篇) 优秀英语作文范文 篇一Title: The Benefits of ReadingIntroduct...
未来的英语作文【推荐3篇】 未来的英语作文 篇一:机器翻译的崛起随着科技的不断进步,机器翻译在未来的发展中将起到越来越重要的作用...
五年级英语作文书【实用3篇】 五年级英语作文书 篇一My Favorite AnimalMy favorite animal is...
英语哲理自信句子(优质5篇) 英语哲理自信句子 篇一自信是一种珍贵的品质,它可以帮助我们在生活中取得成功,克服困难,并实现自己的梦...
坚持不懈英语作文(实用3篇) 坚持不懈英语作文 篇一Title: The Power of PersistenceIntroduc...
朋友英语作文300字(精彩3... 朋友英语作文300字 篇一My Best FriendI would like to talk ab...
小学英语作文我们的班会(优选... 小学英语作文我们的班会 篇一Our Class MeetingOur class recently ...
介绍猫的英语作文(推荐6篇) Introduction to Cats (Part 1)Cats are one of the m...
家人的英语作文【最新6篇】 家人的英语作文 篇一My FamilyMy family is the most important...
克服困难的英语作文【通用4篇... 克服困难的英语作文 篇一Overcoming Difficulties in Learning En...
后天英文观后感【优选3篇】 后天英文观后感 篇一The Day After Tomorrow: A Tale of Enviro...
英语邀请函接受范文(实用6篇... 英语邀请函接受范文 篇一Dear [Name],I hope this letter finds y...
英语作文英汉互译(最新3篇) 篇一:英语作文英汉互译英文标题:The Importance of Learning English...
my dream job英语... 篇一:My Dream JobMy dream job is to become a success...