`
_jia_shun
  • 浏览: 24901 次
  • 性别: 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++大学教程,一本适合初学者的入门教材(part1)

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

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

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

    C++MFC教程

    1、需要有好的C/C++基础。正所谓“磨刀不误砍柴工”,最开始接触VC时不要急于开始Windows程序开发,而是应该进行一些字符界面程序的编写。这样做的目的主要是增加对语言的熟悉程度,同时也训练自己的思维和熟悉一些...

    JNI完全技术手册 带完整书签

    Chap11:如何在C/C++中调用Java. 80 1.环境搭建... 81 2.初始化虚拟机... 83 3.访问类方法... 85 4访问类属性... 87 5.访问构造函数... 88 6.数组处理... 89 7.中文处理... 89 8.异常... 91 9.线程和同步...

    C++大学教程

    C++大学教程(目录) 第1章 计算机与C++编程简介-------------------------------------------------1 1.1 简介--------------------------------------------------------------1 1.2 什么是计算机--------...

    C++ Primer中文版(第5版)李普曼 等著 pdf 1/3

     第Ⅰ部分 C++基础 27  第2章 变量和基本类型 29  2.1 基本内置类型 30  2.1.1 算术类型 30  2.1.2 类型转换 32  2.1.3 字面值常量 35  2.2 变量 38  2.2.1 变量定义 38  2.2.2 变量声明和定义的关系 41  ...

    C++Primer(第5版 )中文版(美)李普曼等著.part2.rar

     第Ⅰ部分 C++基础 27  第2章 变量和基本类型 29  2.1 基本内置类型 30  2.1.1 算术类型 30  2.1.2 类型转换 32  2.1.3 字面值常量 35  2.2 变量 38  2.2.1 变量定义 38  2.2.2 变量声明和定义的关系 41  ...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    面向对象编程的基础 要了解面向对象编程(OOP)的基本概念,需要理解 OOP 的三个主要概念,它们撑起 了整个 OOP 的框架。这三个概念是:封装、继承性和多态性。除此以外,还需了解对象、 类、消息、接口、及抽象等...

    java大学实用教程课件

    老师上课用的ppt,有每一章节的实例 第1章 Java语言概述 本章导读  1.Java语言的诞生 2.学习Java的必要性 3.java 的特点 4.java 与C/C++之关系 5.Java运行平台 6.Java程序开发 7.SDK1.5编译器的新规定 1.1 Java...

    数据结构(C++)有关练习题

    实验一 复习C++有关知识 实验目的: 通过实验掌握下列知识: 1、复习C++有关基本知识; 2、熟悉VC编程、编译和调试环境; 内容及步骤: 编写一个类Complex,定义复数的加法、减法、乘法和除法运算,...

    PHP基础教程 是一个比较有价值的PHP新手教程!

    标题:PHP基础教程 出处:风流的CG网络日志 时间:Mon, 28 Aug 2006 07:24:34 +0000 作者:yufeng 地址:http:///read.php?38 内容: 提供给新手学习的 PHP新手教程,是一个比较有价值的PHP新手教程! 一、PHP...

    C#语言教程入门 docx

    本教程将告诉您基础的 C# 编程,同时将向您讲解 C# 编程语言相关的各种先进理念。 现在开始学习 C#! C# 在线工具 谁适合阅读本教程? 本教程有助于初学者理解基础的 C# 编程。在学习完本教程后,您将到达一个...

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...

    Java2简明教程

    全书共12章,主要包括:Java 2编程基础、面向对象编程原理、接口、包、字符串类String和StringBuffer、异常处理、输入和输出、多线程、Java小程序、GUI布局管理、对象序列化、内隐类、Adapter类和事件处理等,非常...

    MySQL 5.1中文手冊

    2.7. 在其它类Unix系统中安装MySQL 2.8. 使用源码分发版安装MySQL 2.8.1. 源码安装概述 2.8.2. 典型配置选项 2.8.3. 从开发源码树安装 2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从...

    PL/SQL 基础.doc

    PL/SQL 基础,一个不错的 PL/SQL 参考手册。内容预览: ---- 第一章 PL/SQL 简介 ---- 1. Oracle应用编辑方法概览 1) Pro*C/C++/... : C语言和数据库打交道的方法,比OCI更常用; 2) ODBC 3) OCI: C语言和...

    MYSQL中文手册

    2.7. 在其它类Unix系统中安装MySQL 2.8. 使用源码分发版安装MySQL 2.8.1. 源码安装概述 2.8.2. 典型配置选项 2.8.3. 从开发源码树安装 2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在...

    MySQL 5.1官方简体中文参考手册

    2.7. 在其它类Unix系统中安装MySQL 2.8. 使用源码分发版安装MySQL 2.8.1. 源码安装概述 2.8.2. 典型配置选项 2.8.3. 从开发源码树安装 2.8.4. 处理MySQL编译问题 2.8.5. MIT-pthreads注意事项 2.8.6. 在Windows下从...

    MySQL5.1参考手册官方简体中文版

    张伟,华东交通大学。 摘要 这是MySQL参考手册 它涉及MySQL 5.1至5.1.2-alpha版本。 文档生成于: 2005-11-15 -------------------------------------------------------------------------------- 目录 ...

Global site tag (gtag.js) - Google Analytics