这两天没事的时候重写了下string类。
设计的类要简单易用,可扩展性强,
不写还好,写了就出毛病,不出毛病还不好了,
至少让俺重视了运算符重载的问题。尤其是friend。
可以先写最基本的功能,然后测试,然后再添加,再测试,
这样可以将错误减少很多,不至于出现了一大堆,搞的自己的心情很低落。
下午冒着雨回来找那个错误,搜了好久,问题是解决了,可是只是暂时性的解决。
标准C++是没有iostream.h这个头文件的。所以这段代码在gcc或者vs下面是编译不通的。
然后突然看到人家说已经说明为friend就不必在类外的定义里面再加上那个friend。这样
就可以不用iostream.h这个头文件了,然后在2个重载的istream和ostream前面加上std::就可以了。
到gcc调试的时候又出问题了,最后一个群的哥们儿告诉俺在重载输出流<<的时候把那个MyString
前面加上一个const就没事了,输出流嘛,当然不能改变当前对象了。你懂的。下面再把调试好的代码
重新贴出来。功能比较少,如果有需要的话扩展下也是比较
简单的。main里面只是部分测试数据,希望大家提下自己的看法。
转载请注明出处,谢谢!
MyString.h
#ifndef MYSTRING_H
#define MYSTRING_H
#include <cstring>
#include <iostream>
class MyString{
public:
MyString();//default constructor
MyString(const char *ndata);//constructor with argument
MyString(const MyString &s);//copy constructor
MyString& operator=(const MyString &s);//assignment constructor
int getLength();//获得串的长度
MyString subString(int n);//获得指定长度的字符串,返回一个对象
char operator[](int n);//重载[],支持下标访问
MyString operator+(const MyString &s);//重载+
MyString& operator+=(const MyString &s);//重载+=
//下面几个也可以用成员函数来重载
friend bool operator>(const MyString &s1, const MyString &s2){
return strcmp(s1.data,s2.data) > 0 ? true : false;
}
friend bool operator<(const MyString &s1, const MyString &s2){
return strcmp(s1.data,s2.data) < 0 ? true : false;
}
friend bool operator==(const MyString &s1, const MyString &s2){
return strcmp(s1.data,s2.data) == 0 ? true : false;
}
friend bool operator!=(const MyString &s1, const MyString &s2){
return strcmp(s1.data,s2.data) == 0 ? false : true;
}
//注意重载<<的时候不能改变对象的状态,不然g++的时候就编译不成功了
friend std::ostream& operator<<(std::ostream &os, const MyString &s);
friend std::istream& operator>>(std::istream &in, MyString &s);
~MyString();//destructor
private:
char *data;
int size;//串的长度
void copy(const char *p, int nsize);//完成copy功能
};
#endif
MyString.cpp
#include "MyString.h"
#include <iostream>
#include <cstring>
using namespace std;
MyString::MyString(){
data = new char[1];
*data = '\0';
size = 0;
}
MyString::MyString(const char *ndata){
size = strlen(ndata);
copy(ndata, size);
}
MyString::MyString(const MyString &s){
size = s.size;
copy(s.data, size);
}
MyString& MyString::operator=(const MyString &s){
if (&s != this){
delete []data;
copy(s.data, s.size);
size = s.size;
}
return *this;
}
int MyString::getLength(){
return size;
}
MyString MyString::subString(int n){//获得指定长度的字符串,返回一个对象
MyString temp;
temp.size = n;
if (size >= n){
delete []temp.data;
temp.data = new char[n + 1];
char *odata = temp.data;//保存首地址
int count = 0;//计数
char *ndata = data;//保存当前对象的首地址
while (n != count){
*odata++ = *ndata++;
count++;
}
*odata = '\0';
}
return temp;
}
char MyString::operator[](int n){//重载[],支持下标访问
if (size >= n){
char *temp = data;
int count = 1;//计数
while (n != count){
temp++;
count++;
}
return *temp;
}
return '\0';//越界返回\0
}
MyString MyString::operator+(const MyString &s){
MyString temp;
temp.size = size + s.size;
temp.data = new char[temp.size + 1];//申请合适的内存
char *tdata = temp.data;//保存temp的data首地址
char *thdata = data;//保存当前对象的data的首地址
while (*thdata){
*tdata++ = *thdata++;
}
char *sdata = s.data; //保存+右边的对象的首地址
while (*sdata){
*tdata = *sdata;
tdata++;
sdata++;
}
*tdata = '\0';//补0
return temp;
}
MyString& MyString::operator+=(const MyString &s){
char *odata = data;//保存旧数据的地址
size += s.size;
copy(data, size + 1);
strcat(data,s.data);
delete []odata; //删除旧的
return *this;
}
ostream& operator<<(ostream &os, const MyString &s){
return os<<s.data;
}
istream& operator>>(istream &in, MyString &s){
char buf[1024];//字符缓冲区
in>>buf;
s.size = strlen(buf);
char *ndata = new char[s.size + 1];
char *temp = ndata; //保存ndata的首址
int i = 0;
while (s.size != i){
*temp = buf[i];
temp++;
i++;
}
*temp = '\0';
s.data = ndata;
return in;
}
MyString::~MyString(){
if (data){
delete []data;
size = 0;
}
}
void MyString::copy(const char *p, int nsize){
data = new char[nsize + 1];
if (*p != '\0'){
strcpy(data,p);
}else//空对象来初始化一个空对象
*data = '\0';
}
int main(void)
{
MyString s1("hello"),s2(s1),s3,s4(s3);
cin>>s3;
cout<<s3;
s4 = s3 + s1;
cout<<s4<<endl;
cout<<(s1 + s2)<<endl;
cout<<s1.subString(5)<<endl;
s1 =s1 + s2;
if (s1 > s2)
cout<<"s1 > s2";
else if (s1 == s2)
cout<<"s1 == s2";
else
cout<<"s1 < s2";
cout<<s1.getLength()<<endl;
return 0;
}