【C++】面试题:模拟实现string类(版本一:用深度拷贝来实现 )

来源:互联网 发布:python实现堆排序算法 编辑:程序博客网 时间:2024/06/06 10:06

    在学习C++时,我们发现string这个类功能很强大,所以我们模拟实现以下它,虽然不能像库函数里实现的那么强大和完美,但是有助于我们更加熟悉的使用string。此篇博客我将用深度拷贝来实现。这里深度拷贝简单来说就是除了拷贝对象的值以外,若对象有其所指向的一块空间,则同时为新创建的对象也开辟一块空间,再拷贝内容。除了深度拷贝,写时拷贝也能实现string类,并且写时拷贝更加高效,写时拷贝具体是什么,我将再下篇用写时拷贝实现string类进行介绍。

    这里我简单的实现了string类的基本函数和几个功能函数:

#define _CRT_SECURE_NO_WARNINGS 1 #include<iostream>#include<cstring>#include<cassert>using namespace std;class String{friend ostream& operator<<(ostream &os, const String &s);public:String(char *str = ""):_str(new char[strlen(str) + 1]), _sz(strlen(str)), _capacity(strlen(str) + 1){strcpy(_str, str);}~String(){if (_str != NULL){delete[] _str;_sz = 0;_capacity = 0;}}String(const String &s):_str(new char[strlen(s._str) + 1]){_sz = s._sz;_capacity = s._capacity;strcpy(_str, s._str);}String& operator=(String s)     //赋值运算符重载的现代写法{_sz = s._sz;_capacity = s._capacity;std::swap(s._str, _str);return *this;}const char *c_str(){return _str;}void CheckCapacity(int sz)   //检测容量是否够用,不够则重新开辟{int tmp = 0;if (_capacity<(sz + _sz + 1)){tmp = (2 * _capacity > _capacity + sz) ? 2 * _capacity : _capacity + sz;char *str = new char[_capacity];strcpy(str, _str);delete[] _str;_str = new char[tmp];strcpy(_str, str);_capacity = tmp;}}void PushBack(char ch)          //尾部插入字符{CheckCapacity(1);_str[_sz++] = ch;_str[_sz] = '\0';_sz += 1;}char operator[](int sz){return _str[sz];}String &operator+=(const String&s){CheckCapacity(strlen(s._str));strcat(_str, s._str);return *this;}size_t find(const String& s, size_t pos = 0) const  //在一个字符串里查找子串,返回第一次出现的位置下标{char *str1 = _str;char *src = _str;char *str2 = s._str;int count = 1;while (*src){str2 = s._str;str1 = src;while ((*str1) && (*str2) && (*str1 == *str2)){str1++;str2++;}if (*str2 == '\0'){return count;}count++;src++;}return 0;}String& Insert(size_t pos1, const String& s)  //给定位置插入字符串{//assert((pos1 > 0) || (pos1 < strlen(_str + 1)));CheckCapacity(strlen(s._str));char *tmp = new char[strlen(_str)];strcpy(tmp, _str + pos1-1);_str[pos1 - 1] = '\0';*this += s;strcat(_str, tmp);_sz += strlen(s._str);return *this;}private:char *_str;int _sz;int _capacity;};ostream& operator<<(ostream &os, const String &s){os << s._str;return os;}void test1()  //测试拷贝构造{String s1("hello");String s2(s1);cout << s2 << endl;}void test2()  //测试赋值操作符{String s1("hello");String s2;s2 = s1;cout << s2 << endl;}void test3()  //测试+=操作符重载{String s1("hello");String s2(" world");s1 += s2;cout << s1 << endl;}void test4()  //测试pushback函数{String s1("worl");s1.PushBack('d');cout << s1 << endl;}void test5()  //测试find函数{String s1("hello world");String s2("world");int ret = s1.find(s2);cout << ret << endl;}void test6()   //测试[]运算符重载{String s1("hello world");cout << s1[2] << endl;}void test7()  //测试insert函数{String s1("hello");s1 = s1.Insert(2, " world");cout << s1 << endl;}int main(){test1();test2();test3();test4();test5();test6();test7();getchar();return 0;}

    私有成员除了一个char* 类型的字符串,还有一个_sz(字符串的长度)和_capacity(字符串开辟空间的大小)来维护字符串。在需要插入字符或者字符串的时候,需要先检测空间大小是否足够,不够则需要重新开辟空间,这时候需要用到_sz,_capacity。

    除了以上这些功能,库里的string其实有更多的功能,感兴趣可以点击这个链接自己搜索看看:http://www.cplusplus.com/

0 0
原创粉丝点击