C++大学基础教程_11_10_实例研究:String类

//String.h

#ifndef STRING_H_
#define STRING_H_

#include <iostream>
using namespace std;

class String
{
	//,将重载运算符<< 和 >> 设为友元函数,二元运算符的重载运算符函数可以作为成员
	//函数的条件是仅当左操作数是该类所在类的对象时;
	friend ostream &operator<<(ostream &,const String &);
	friend istream &operator>>(istream &,String &);
public:
	String(const char * = "");//构造函数,将char型转换成String型
	String(const String &);//拷贝构造函数
	~String();
	const String &operator=(const String &);//两字符串复制函数
	const String &operator+=(const String &);//两字符串相加
	const String &operator+=(const char *);//两字符串相加
	bool operator!();//判断是否为空字符串
	bool operator==(const String &) const;//判断是否两字符串相等
	bool operator!=(const String &right) const   //判断两字符串是否不等
	{
		return !(*this == right);
	}
	bool operator<(const String &) const;
	bool operator>(const String &right) const //写内联函数的时候忘记写参数,!!!!!
	{
		return right < *this;
	}
	bool operator<=(const String &right) const
	{
		return !(*this > right);
	}
	bool operator>=(const String &right) const
	{
		return !(*this < right);
	}
	char &operator[](int);//重载[],
	char operator[](int) const;
	void operator()(int,char) const;//替换某个位置的元素
	String operator()(int,int = 0) const;//截取两个数字位之间的字符
	void setString(const char *);//效用函数
private:
	int length;//字符串中字符个数
	char *sPtr;//指针sPtr,指向代表字符串的额动态内存分配
	
};

#endif
//String.cpp

#include "String.h"
#include <iostream>
#include <iomanip>
using namespace std;

istream &operator>>(istream &input,String &right)
{
	char *temp = new char[100];
	input >> setw(100) >> temp;
	right = temp;
	delete [] temp;
	return input;
}
ostream &operator<<(ostream &output,const String &right)
{
	int i;
	for(i=0;i<right.length;i++)  //ouput << right.sPtr;
		output << right.sPtr[i];
	return output;
}

void String::setString(const char *string)
{
	sPtr = new char[strlen(string)+1];//把这一句写成[strlen(string+1)]
	                                                  //我是得有多有才!!!
	if(string!=0)
	{	for(int i=0;i<strlen(string);i++)
			sPtr[i] = string[i];
        sPtr[strlen(string)] = '\0';
	}
    /* if(string!=0) strcpy(sPtr,string); */
	else
		sPtr = '\0';
}

String::String(const char *right)
	:length((right!=0)? strlen(right) : 0) //构造器
{
	cout << "Conversion (and default) constructor: " << right << endl;
	setString(right);
}

String::String(const String &s)//拷贝构造函数
	:length(s.length)
{
	cout << "Copy constructor: " << s.sPtr << endl;
    setString(s.sPtr);
}

String::~String()
{
	cout << "Destructor: " << sPtr << endl;
	delete [] sPtr;
}

//两字符串复制函数
const String &String::operator=(const String &right)
{
	cout << "operator= called." << endl;
	if(&right != this)
	//if(sPtr != right.sPtr)//防止同一字符串自我复制
	{
		delete [] sPtr;
		length = right.length;
		/*
		sPtr = new char[right.length];
		for(int i=0;i<length;i++)
			sPtr[i] = right.sPtr[i];
		*/
		setString(right.sPtr);
	}
	else 
		cout << "Attempted assignment of a string to itself." << endl;
	return *this;
}

const String &String::operator+=(const String &right)//两字符串相加
{
	size_t newLength= length + right.length;
	char *temp = new char[newLength+1];
	for(int i=0;i<length;i++)  //strcpy(temp,sPtr);
		temp[i] = this->sPtr[i];
	strcpy(temp+length,right.sPtr);
	delete [] sPtr;
	sPtr = temp;
	length = newLength;
	return *this;
}
const String &String::operator+=(const char *s)//两字符串相加
{
	if(s != 0)
	{
		size_t newLength = length + strlen(s);
	    char *temp = new char[newLength+1];
		strcpy(temp,sPtr);
		for(int i=length;i<newLength;i++)
			temp[i] = s[i-length];
		temp[newLength] = '\0';
		delete [] sPtr;
		sPtr = temp;
		length = newLength;
	}
	return *this;
}

bool String::operator!()//判断是否为空字符串
{
	 //(length == 0)? true: false;
	if(length == 0)
		return true;
	return false;
}

bool String::operator==(const String &right) const//判断是否两字符串相等
{
	if(length == right.length)
	{
		for(int i=0;i<length;i++)
			if(sPtr[i] != right.sPtr[i])
				return false;
	    return true;
	}
	return false;
}

//比较两个字符串如abbbbbbb<abbb   false
//                            askjdh<hj       true
//若两者头部有相同的部分,则比较不同的部分如a<h
bool String::operator<(const String &right) const
{
	if(length < right.length)
	{	
		//先判断两个字符串有没有不相同的
		for(int i=0;i<length;i++)
		{	if(sPtr[i] != right.sPtr[i])
			{	
				if(sPtr[i] < right.sPtr[i])
					return true;  // abb<abccc ? true   
				return false;//abb<abac ? false
			}
		}    
		return true;//abb<abbkajsfh ? true
	}
	else if(length == right.length)
	{
		for(int i=0;i<length;i++)
		{
			if(sPtr[i] != right.sPtr[i])
			{	
				if(sPtr[i] < right.sPtr[i])
					return true;  //abbbb<abcdc ? true
				return false; //abbbb<ababb ? false
			}
		}
		return false; //abbbb<abbbb ? false
	}
	else  //length > right.length
	{
		for(int i=0;i<right.length;i++)
		{
			if(sPtr[i] != right.sPtr[i])
			{
				if(sPtr[i] < right.sPtr[i])
					return true; //abbbb<abd ? true
				return false; //abbbb<aba ? false
			}
		}
		return false;// abbbb<ab ? false
	}//end else
}//end operator< function

char &String::operator[](int number)//重载[],
{
	if(number<0 || number>=length)
	{	
		cout << "Error: number " << number << "out of range." << endl;
		exit(1);
	}
	return sPtr[number];
}
char String::operator[](int number) const
{
	if(number<0 || number>=length)
	{	
		cout << "Error: number " << number << "out of range." << endl;
		exit(1);
	}
	return sPtr[number];
}

String String::operator()(int index,int subLength) const//截取两个数字位之间的字符
{
	int len;
	if(index<0 || subLength<0 || index>subLength)
		return "";
	else if(index>=0 && subLength<=length)
		len = subLength;
	else if(index>=0 && subLength>length)
		len = length-index;
	char *tempPtr = new char[len+1];
	strncpy(tempPtr,&sPtr[index],len);
	tempPtr[len] = '\0';
	String tempString(tempPtr);
	delete [] tempPtr;
	return tempString;//写成return temPtr运行的时候会出现乱码
}

void String::operator()(int number,char s) const//替换某个位置的元素
{
	this->sPtr[number] = s;
}
//_11_10_main.cpp

#include "String.h"
#include <iostream>
using namespace std;

int main()
{
	{//这一对大括号是为了把析构函数的调用弄出来加上去的,可以去掉
	String str1("happy");
	String str2(" birthday");
	String str3;
	cout << "str1 is \"" << str1 << "\"; str2 is \"" 
		                         << str2 << "\"; str3 is \""
								 << str3 << "\"\n";
	cout << boolalpha << "The results of comparing str2 and str1:"
		   << "\nstr2 == str1 yields " << (str2==str1)
		   << "\nstr2 ! = str1 yields " << (str2!=str1)
		   << "\nstr2  >  str1 yields " << (str2>str1)
		   << "\nstr2  <  str1 yields " << (str2<str1)
		   << "\nstr2 >= str1 yields " << (str2>=str1)
		   << "\nstr2 <= str1 yields " << (str2<=str1)
		   << endl;
	cout << "Testing !str3:" << endl;
	if(!str3)
	{
		cout << "str3 is empty;assigning str1 to str3;" << endl;
		str3 = str1;
		cout << "str3 is \"" << str3 << "\"\n";
	}
	cout << "str1 += str2 yields " << endl;
	str1 += str2;
	cout << "str1 = " << str1 << endl;
	cout << "str1 += \" to you \" yields" << endl;
	str1 += " to you";
	cout << "str1 = " << str1 << endl;
	cout << "The substring of str1 starting at \n"
		   << "location 0 for 14 characters,str1(0,14), is:\n"
		   << str1(0,14) << endl;//对应的函数部分有错误提示
	cout << "The substring of str1 starting at \n"
		   << "location 15,str1(3,15), is:\n"
		   << str1(3,15) << endl;
	String *sPtr0 = new String(str1);
	cout << "*sPtr0 = " << *sPtr0 << endl;
	cout << "assigning *sPtr0 to *sPtr0" << endl;
	*sPtr0 = *sPtr0;
	cout << "*sPtr0 = " << *sPtr0 << endl;
	*sPtr0 = str2;//注意咯!!!!!
	cout << "*sPtr0 = " << *sPtr0 << endl;
	
	delete sPtr0;//写成这样就会错误,delete [] sPtr0;因为这是一个指向对象的指针啊啊啊
	
	str1(0,'H');
	str1(6,'B');
	cout << "str1 after atr1[0] = 'H' and str[6] = 'B' is:\n"
		   << str1 << endl;
	}
	system("pause >> cout");
	return 0;
}

 




 

猜你喜欢

转载自jia-shun.iteye.com/blog/2092723