//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; }
相关推荐
这个压缩包“每天学点C++(C++实例教程:教程+源码)01string容器.zip”显然是为了帮助初学者通过实例来学习`std::string`的用法。 首先,`std::string` 是一个动态数组,可以自动调整大小以容纳更多的字符。你可以...
### C++大学基础教程课后习题答案解析 #### 标题:《C++大学教程第五版》课后习题答案 #### 描述:《C++大学教程第五版》课后习题答案 #### 标签:c++ #### 部分内容分析 在这一部分的内容中,我们将会详细解析...
从给定的文件信息中,我们可以提取到关于C++编程语言中的类定义、构造函数、成员函数以及如何在主程序中实例化并调用这些功能的关键知识点。以下是对这些知识点的详细阐述: ### 类定义与成员变量 在C++中,类是一...
8.10 实例研究:String类 8.11 重载十十与—— 8.12 实例研究:Date类 小结 术语 自测练习 自测练习答案 练习 第9章 继承 9.1 简介 9.2 继承:基类和派生类 9.3 Protected成员 9.4 把基类指针强制转换为派生...
以上只是C++基础的冰山一角。随着学习深入,你还将接触到更多概念,如运算符、控制结构(条件语句、循环)、函数、数组、指针、类和对象等。每个主题都有其独特的细节和应用场景,理解并熟练掌握这些知识点是成为C++...
在本教程中,我们将深入探讨如何模仿`std::string`的功能来创建一个自定义的字符串类。这个过程可以帮助我们理解字符串内部的工作原理,以及如何有效地管理字符数组。 首先,我们要创建一个名为`MyString`的类,它...
10. **模板**:模板是C++的泛型编程工具,实例会讲解函数模板和类模板的使用。 11. **STL迭代器**:迭代器是访问STL容器元素的主要方式,实例会介绍如何使用迭代器遍历和操作容器中的元素。 12. **多线程编程**:...
"C++基础大学教程例题"这个主题旨在帮助初学者通过实际的编程例子深入理解C++语言。下面将详细介绍C++的基础知识,并结合可能在教程中出现的例题进行解析。 C++是一种静态类型的、编译式的、通用的、大小写敏感的、...
本教程“每天学点C++”旨在通过实例教学,帮助初学者逐步掌握C++的核心概念和技术。 在C++中,键盘输入是程序与用户交互的基本方式之一。在描述中提到的“键盘输入.zip”压缩包,很显然包含了一些关于C++键盘输入的...
通过深入研究"每天学点C++"中的实例教程,你将能够掌握C++的符号重载技巧,这将使你的代码更具灵活性和可读性,同时也为解决更复杂的编程问题奠定基础。记住,实践是掌握任何技能的关键,所以不要害怕尝试和修改这些...
标题 "c++4_OneThreeOne_C++_" 暗示这是一个关于C++编程语言的学习资料,特别是可能聚焦于C++11、C++14、C++17这三个标准(OneThreeOne可能代表11、14、17)。描述中的 "cpp learning code" 确认了这是一个关于C++...
"每天学点C++"的实例教程旨在帮助初学者逐步理解并掌握C++的基本概念和编程技巧。通过源码的学习,可以更直观地了解代码如何工作,从而提升编程能力。 在“01C++初识”这个部分,我们将首先接触到C++的基础知识。这...
《每天学点C++》是一本面向初学者和进阶者的C++实例教程,它结合了理论知识与实际操作,旨在帮助读者通过实践来掌握这门强大的编程语言。本教程包含了一个机房预约系统的源码,这是一个典型的C++应用程序实例,能够...
标题:“C++/CLI教程”指的是一个专门针对C++/CLI(C++ Common Language Infrastructure)编程语言的教程。C++/CLI是微软设计的一种编程语言,旨在将C++的强大功能与.NET平台的互操作性相结合。它允许开发者使用C++...
本教程旨在帮助初学者理解C++编程的基础,并通过实例来深化理解。C++不仅继承了C语言的高效性和灵活性,还引入了面向对象编程的概念,如类、对象、封装、继承和多态性。 "程序编译全过程"是C++学习中的关键部分。...
本教程将深入探讨C++中的函数,包括它们的定义、参数传递、返回值以及作用域规则。通过实例学习,我们将更深入地理解这些概念。 首先,函数的定义是声明其功能、输入参数和返回类型的过程。在C++中,函数定义的一般...
在C++中,还有一种特殊的结构体类型叫做类(class),它是面向对象编程的基础。类除了拥有结构体的特性外,还支持访问控制(public、private、protected)、继承、多态等特性。类通常用于实现更高级别的抽象和封装。...
本大学C++课程语言教程旨在帮助学生深入理解C++的基础概念、语法和高级特性,从而能够编写出高效、可维护的代码。 1. **基础概念** - 变量:存储数据的容器,有不同数据类型,如整型(int)、浮点型(float/double)、...
《C++ 编程基础教程》是一门专为初学者设计的C++编程入门课程,旨在帮助学习者从零开始掌握这一强大而广泛使用的编程语言。C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化编程,也支持面向...
例如,可能会介绍如何使用Graphics类进行画布操作,Pen类绘制线条和边框,SolidBrush类填充颜色,Font类和StringFormat类处理文本布局。 GDI+教程中的内容可能涵盖以下几个关键知识点: 1. **GDI+基础**:介绍GDI+...