一直以来 String 都是 C++ 里最常被使用到的数据结构,今天有必要熟悉一下其实现。这里学习并小记之。
此处我只会实现其最基础的几个函数,异常,线程安全等细节也都未考虑。写完发现还是用到了 #include <string.h> 头文件,有点囧
具体实现参考自:http://noalgo.info/382.html(C++中String类的实现)
代码如下,并附有注释:
#include <iostream>
#include <assert.h>
#include <string.h>
using namespace std;
class MyString
{
public:
MyString(const char *str = NULL);
MyString(const MyString &mystr);
~MyString();
MyString operator+(const MyString &mystr) const;
MyString& operator=(const MyString &mystr);
MyString& operator+=(const MyString &mystr);
bool operator==(const MyString &mystr) const;
char& operator[](size_t index);
const char* c_str() const;
size_t size() const;
friend istream& operator>>(istream &is, MyString &mystr); //返回 istream& 的目的是为了能够连续 >>,如 cin >> str1 >> str2;
friend ostream& operator<<(ostream &os, MyString &mystr);
private:
char *data;
size_t length;
};
MyString::MyString(const char *str)
{
if(NULL == str)
{
data = new char[1];
data[0] = '\0';
length = 0;
}
else
{
length = strlen(str);
data = new char[length + 1];
strcpy(data, str);
}
}
MyString::MyString(const MyString &mystr)
{
length = mystr.length;
data = new char[length + 1];
strcpy(data, mystr.data);
}
MyString::~MyString()
{
delete[] data;
length = 0;
}
MyString MyString::operator+(const MyString &mystr) const
{
size_t len = length + mystr.length;
char *data = new char[len + 1];
strcpy(data, this -> data);
strcat(data + length, mystr.data);
MyString newMyString(data);
delete[] data;
return newMyString;
}
MyString& MyString::operator=(const MyString &mystr)
{
char *pOrig = data;
length = mystr.length;
data = new char[length + 1];
strcpy(data, mystr.data);
delete[] pOrig;
return *this;
}
MyString& MyString::operator+=(const MyString &mystr)
{
size_t len = length + mystr.length;
char *pOrig = data;
data = new char[len + 1];
strcpy(data, pOrig);
strcat(data + length, mystr.data);
length = len;
delete[] pOrig;
return *this;
}
bool MyString::operator==(const MyString &mystr) const
{
if(0 == strcmp(data, mystr.data))
{
return true;
}
else
{
return false;
}
}
char& MyString::operator[](size_t index)
{
if(index >= 0 && index < length)
{
return data[index];
}
else
{
assert(0);
}
}
const char* MyString::c_str() const
{
return data;
}
size_t MyString::size() const
{
return length;
}
istream& operator>>(istream &is, MyString &mystr)
{
char tmp[1000]; //此处的实现还欠考虑,还是有溢出的可能
is >> tmp;
mystr = MyString(tmp);
return is;
}
ostream& operator<<(ostream &os, MyString &mystr)
{
os << mystr.data;
return os;
}
int main()
{
MyString str1;
cout << "Please enter a string:" << endl;
cin >> str1;
cout << str1 << "\nlength : " << str1.size() << endl;
char c1[] = "hello";
char c2[] = "world";
MyString str2(c1), str3(c2);
MyString str4 = str2 + str3;
cout << str4 << endl;
str2 += str3;
if(!(str2 == str3))
{
cout << str2 << " != " << str3 << endl;
}
cout << str2[1] << endl;
const char *pc = str1.c_str();
cout << pc << endl;
return 0;
}
编写的过程中遇到了一些注意点,总结如下:
1、关于带有默认参数的函数声明与定义:
默认参数只能指定一次,在声明中指定了就不能在定义中指定,反过来也一样。
2、const 成员函数:
由于 const 成员函数需要保证不修改成员数据,所以 const 成员函数能够调用的成员函数必须也得是 const 成员函数。