C++ 继承 001:全面的MyString

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

发布了77 篇原创文章 · 获赞 3 · 访问量 3057

猜你喜欢

转载自blog.csdn.net/BLUEsang/article/details/105117644