`
_jia_shun
  • 浏览: 27232 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
社区版块
存档分类
最新评论

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;
}

 




 

  • 大小: 166.6 KB
  • 大小: 197 KB
分享到:
评论

相关推荐

    每天学点C++(C++实例教程:教程+源码)01string容器.zip

    这个压缩包“每天学点C++(C++实例教程:教程+源码)01string容器.zip”显然是为了帮助初学者通过实例来学习`std::string`的用法。 首先,`std::string` 是一个动态数组,可以自动调整大小以容纳更多的字符。你可以...

    《C++大学教程第五版》课后习题答案

    ### C++大学基础教程课后习题答案解析 #### 标题:《C++大学教程第五版》课后习题答案 #### 描述:《C++大学教程第五版》课后习题答案 #### 标签:c++ #### 部分内容分析 在这一部分的内容中,我们将会详细解析...

    c++大学基础教程答案

    从给定的文件信息中,我们可以提取到关于C++编程语言中的类定义、构造函数、成员函数以及如何在主程序中实例化并调用这些功能的关键知识点。以下是对这些知识点的详细阐述: ### 类定义与成员变量 在C++中,类是一...

    C++大学教程,一本适合初学者的入门教材(part1)

    8.10 实例研究:String类 8.11 重载十十与—— 8.12 实例研究:Date类 小结 术语 自测练习 自测练习答案 练习 第9章 继承 9.1 简介 9.2 继承:基类和派生类 9.3 Protected成员 9.4 把基类指针强制转换为派生...

    C++基础实例教程

    以上只是C++基础的冰山一角。随着学习深入,你还将接触到更多概念,如运算符、控制结构(条件语句、循环)、函数、数组、指针、类和对象等。每个主题都有其独特的细节和应用场景,理解并熟练掌握这些知识点是成为C++...

    String_C++_order9wd_string_

    在本教程中,我们将深入探讨如何模仿`std::string`的功能来创建一个自定义的字符串类。这个过程可以帮助我们理解字符串内部的工作原理,以及如何有效地管理字符数组。 首先,我们要创建一个名为`MyString`的类,它...

    经典c++程序100例(完整版)_C++程序设计_经典c++程序100例_

    10. **模板**:模板是C++的泛型编程工具,实例会讲解函数模板和类模板的使用。 11. **STL迭代器**:迭代器是访问STL容器元素的主要方式,实例会介绍如何使用迭代器遍历和操作容器中的元素。 12. **多线程编程**:...

    C++基础大学教程例题

    "C++基础大学教程例题"这个主题旨在帮助初学者通过实际的编程例子深入理解C++语言。下面将详细介绍C++的基础知识,并结合可能在教程中出现的例题进行解析。 C++是一种静态类型的、编译式的、通用的、大小写敏感的、...

    每天学点C++(C++实例教程:教程+源码)键盘输入.zip

    本教程“每天学点C++”旨在通过实例教学,帮助初学者逐步掌握C++的核心概念和技术。 在C++中,键盘输入是程序与用户交互的基本方式之一。在描述中提到的“键盘输入.zip”压缩包,很显然包含了一些关于C++键盘输入的...

    每天学点C++(C++实例教程:教程+源码)符号重载.zip

    通过深入研究"每天学点C++"中的实例教程,你将能够掌握C++的符号重载技巧,这将使你的代码更具灵活性和可读性,同时也为解决更复杂的编程问题奠定基础。记住,实践是掌握任何技能的关键,所以不要害怕尝试和修改这些...

    c++4_OneThreeOne_C++_

    标题 "c++4_OneThreeOne_C++_" 暗示这是一个关于C++编程语言的学习资料,特别是可能聚焦于C++11、C++14、C++17这三个标准(OneThreeOne可能代表11、14、17)。描述中的 "cpp learning code" 确认了这是一个关于C++...

    每天学点C++(C++实例教程:教程+源码)01C++初识.zip

    "每天学点C++"的实例教程旨在帮助初学者逐步理解并掌握C++的基本概念和编程技巧。通过源码的学习,可以更直观地了解代码如何工作,从而提升编程能力。 在“01C++初识”这个部分,我们将首先接触到C++的基础知识。这...

    每天学点C++(C++实例教程:教程+源码)机房预约系统.zip

    《每天学点C++》是一本面向初学者和进阶者的C++实例教程,它结合了理论知识与实际操作,旨在帮助读者通过实践来掌握这门强大的编程语言。本教程包含了一个机房预约系统的源码,这是一个典型的C++应用程序实例,能够...

    C++/CLI教程

    标题:“C++/CLI教程”指的是一个专门针对C++/CLI(C++ Common Language Infrastructure)编程语言的教程。C++/CLI是微软设计的一种编程语言,旨在将C++的强大功能与.NET平台的互操作性相结合。它允许开发者使用C++...

    每天学点C++(C++实例教程:教程+源码)程序编译全过程.zip

    本教程旨在帮助初学者理解C++编程的基础,并通过实例来深化理解。C++不仅继承了C语言的高效性和灵活性,还引入了面向对象编程的概念,如类、对象、封装、继承和多态性。 "程序编译全过程"是C++学习中的关键部分。...

    每天学点C++(C++实例教程:教程+源码)函数初识.zip

    本教程将深入探讨C++中的函数,包括它们的定义、参数传递、返回值以及作用域规则。通过实例学习,我们将更深入地理解这些概念。 首先,函数的定义是声明其功能、输入参数和返回类型的过程。在C++中,函数定义的一般...

    每天学点C++(C++实例教程:教程+源码)结构体.zip

    在C++中,还有一种特殊的结构体类型叫做类(class),它是面向对象编程的基础。类除了拥有结构体的特性外,还支持访问控制(public、private、protected)、继承、多态等特性。类通常用于实现更高级别的抽象和封装。...

    大学C++课程语言教程

    本大学C++课程语言教程旨在帮助学生深入理解C++的基础概念、语法和高级特性,从而能够编写出高效、可维护的代码。 1. **基础概念** - 变量:存储数据的容器,有不同数据类型,如整型(int)、浮点型(float/double)、...

    C++ 编程基础教程

    《C++ 编程基础教程》是一门专为初学者设计的C++编程入门课程,旨在帮助学习者从零开始掌握这一强大而广泛使用的编程语言。C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化编程,也支持面向...

    GDI+教程(C++中文版).rar_C++_Vc_gdi_gdi 教程_图形设备

    例如,可能会介绍如何使用Graphics类进行画布操作,Pen类绘制线条和边框,SolidBrush类填充颜色,Font类和StringFormat类处理文本布局。 GDI+教程中的内容可能涵盖以下几个关键知识点: 1. **GDI+基础**:介绍GDI+...

Global site tag (gtag.js) - Google Analytics