欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

相关标签: 面向对象C++

上一篇: 016

下一篇: C++函数学习