C++ 继承 001:全面的MyString
程序员文章站
2024-03-17 18:50:40
...
001:全面的MyString
描述
程序填空,输出指定结果
#include <cstdlib>
#include <iostream>
using namespace std;
int strlen(const char * s)
{ int i = 0;
for(; s[i]; ++i);
return i;
}
void strcpy(char * d,const char * s)
{
int i = 0;
for( i = 0; s[i]; ++i)
d[i] = s[i];
d[i] = 0;
}
int strcmp(const char * s1,const char * s2)
{
for(int i = 0; s1[i] && s2[i] ; ++i) {
if( s1[i] < s2[i] )
return -1;
else if( s1[i] > s2[i])
return 1;
}
return 0;
}
void strcat(char * d,const char * s)
{
int len = strlen(d); //len不过包括0
strcpy(d+len,s); //后面还会cpy一个0
}
class MyString
{
// 在此处补充你的代码
};
int CompareString( const void * e1, const void * e2)
{
MyString * s1 = (MyString * ) e1;
MyString * s2 = (MyString * ) e2;
if( * s1 < *s2 )
return -1;
else if( *s1 == *s2)
return 0;
else if( *s1 > *s2 )
return 1;
}
int main()
{
MyString s1("abcd-"),s2,s3("efgh-"),s4(s1);
MyString SArray[4] = {"big","me","about","take"};
cout << "1. " << s1 << s2 << s3<< s4<< endl;
s4 = s3;
s3 = s1 + s3;
cout << "2. " << s1 << endl;
cout << "3. " << s2 << endl;
cout << "4. " << s3 << endl;
cout << "5. " << s4 << endl;
cout << "6. " << s1[2] << endl;
s2 = s1;
s1 = "ijkl-";
s1[2] = 'A' ;
cout << "7. " << s2 << endl;
cout << "8. " << s1 << endl;
s1 += "mnop";
cout << "9. " << s1 << endl;
s4 = "qrst-" + s2;
cout << "10. " << s4 << endl;
s1 = s2 + s4 + " uvw " + "xyz";
cout << "11. " << s1 << endl;
qsort(SArray,4,sizeof(MyString),CompareString);
for( int i = 0;i < 4;i ++ )
cout << SArray[i] << endl;
//s1的从下标0开始长度为4的子串
cout << s1(0,4) << endl;
//s1的从下标5开始长度为10的子串
cout << s1(5,10) << endl;
return 0;
}
输入
无
输出
1. abcd-efgh-abcd-
2. abcd-
3.
4. abcd-efgh-
5. efgh-
6. c
7. abcd-
8. ijAl-
9. ijAl-mnop
10. qrst-abcd-
11. abcd-qrst-abcd- uvw xyz
about
big
me
take
abcd
qrst-abcd-
需要构造的函数:
1.无参构造函数
2.有参构造函数,参数为char类型
3.复制构造函数
4.重构=,参数为char类型
5.重构cout<<,友元重构,输出MyString中的char *指向的字符串
6.重构=,参数为MyString类型
7.重构+号,为MS+MS
8.重构[int n],返回MS中的指针指向的列表[n]
9.重构+=,参数为char[]类型
10.重构+,友元重构,为char【】+MS
11.重构(int start , int len),返回从start开始的len个字符
私有成员定义
private:
char *p;
int size; //string的长度
无参构造函数
MyString(){
p=new char[2]; //确保分配的是数组
p[0]=0;
//既然是个字符串,里面起码也是个空串,不能让P=NULL
size=0;
}
有参构造函数
MyString(const char *s){ //有参构造
//如果 s==NULL 就出错吧
size = strlen(s);
p=new char [size+1]; //多一个放0
strcpy(p,s); //strcpy的最后一个字符放0
}
重构=,参数为char *
该重构函数返回MS的引用,这是等号的特性,方便连等
MyString &operator=(const char * a){ //重构=
//如果s==NULL 就让他出错
int len=strlen(a);
//如果当前数组不够放,则释放重建
if (size<len){
//若够放,则直接覆盖就行
delete []p;
p = new char[len+1]; //多1用于放0
}
strcpy(p,a);
size= len;
return *this; //返回引用对象
}
建立复制函数——方便以后重构调用
void duplicate(const MyString & s) {
if( size < s.size ) { //否则就不用重新分配空间了
delete []p;
p = new char[s.size+1];
}
//若不重新分配空间,则需要清空p,再进行duplicate
strcpy(p,s.p);
size = s.size;
}
复制函数
MyString(const MyString &a):size(0),p(new char[1]) { //复制函数 ,构造列表初始化
duplicate(a);
}
重构=,参数为MS,用引用可以节省复制的空间
返回引用
同类型=函数需要判断左右指针是否相同!
MyString &operator=(const MyString &a){ //重构=
if (p==a.p)
return *this;
//相同赋值判断,直接返回才不会出错
duplicate(a);
return *this; //返回对象
}
重构<,==,>,返回bool值
bool operator < (const MyString &a) const
{
return strcmp(p,a.p)<0;
}
bool operator ==(const MyString &a) const
{
return strcmp(p,a.p) ==0;
}
bool operator >(MyString &a) const
{
return strcmp(p,a.p)>0;
}
重构 + 号,参数为MS的引用,节省空间
无需返回引用
对象+对象,故加号左边返回对象即可,
对象的引用=对象,故等号左边需返回引用
MyString operator+(const MyString &a){
char *tmp= new char[size + a.size+2];
//新建一个char*,确保能分配一个数组
strcpy(tmp,p);
strcat(tmp,a.p);
MyString os(tmp); //新建成员对象,调用复制函数
delete []tmp;
return os; //返回成员对象
}
重构 +=
需返回引用
MyString &operator+=(const MyString &a){
char *tmp= new char[size +a.size+2];
strcpy(tmp,p);
strcat(tmp,a.p); //要确保左边的实参比右边的大
size+=a.size;
delete []p; //释放当前p,给p赋值
p=tmp; //调用赋值函数
return *this; //返回对象
}
重构【】
返回值需要被赋值,故需返回引用;
char & operator [](int n) const //?
{ //重构[]
return p[n];
}
重构()
MyString operator ()(int start,int len) const
{ //重构()
char *tmp=new char[len+1]; //构建tmp
for (int i=0;i<len;++i)
tmp[i]=p[start+i]; //从start开始逐个赋值进tmp
tmp[len]=0; //最后一个要为0,代表终止
MyString s(tmp); //新建成员对象,调用构造函数
delete []tmp;
return s; //返回新建的对象
}
析构函数
~MyString(){ //析构函数
delete []p;
}
友元函数,重构cout<<;
因为要连续<<,故返回cout的引用;
返回cout的引用,既可以继续实现cout的功能
friend ostream & operator <<(ostream & o,const MyString & a){ //重构cout<<
o<<a.p;
return o; //返回值别忘了
}
友元函数,重构char * + MS;
friend MyString operator +(const char *a ,const MyString &t){ //重构+
MyString tmp(a);
//先复制
tmp+=t;
//再调用+MS的函数
return tmp; //返回新建的成员对象
}
关于何时返回引用,何时返回对象,可参考:
https://www.cnblogs.com/helloweworld/p/3208585.html