📄 string2.cpp
字号:
//string2.cpp
//定义类String的成员函数
#include <iostream.h>
#include <string.h>
#include <assert.h>
#include "string2.h"
// 转换构造函数:把 char* 类型转换为String类型
String:: String(const char *s)
{
cout<<"Convention Constuctor:"<<s<<endl;
length=strlen(s); //计算字符串
sPtr=new char[length+1]; //分配内存
assert(sPtr!=0); //在内存分配失败时中止
strcpy(sPtr, s); //拷贝字符串直接量拷贝到对象中
}
//拷贝构造函数
String:: String(const String ©)
{
cout<<"Copy Constuctor:"<<copy.sPtr<<endl;
length=copy.length; //拷贝构造函数
sPtr=new char[length+1]; //分配内存
assert(sPtr!=0); //在内存分配失败时中止
strcpy(sPtr, copy.sPtr); //拷贝字符串
}
//析构函数
String:: ~String()
{
cout<<"Destructor:"<<sPtr<<endl;
delete []sPtr; //释放内存,收回字符串占用的内存
}
//重载赋值运算符=, 避免自我赋值
const String &String:: operator= (const String &right)
{
cout<<"operator=called"<<endl;
if(&right!=this){ //避免自我赋值
delete []sPtr; //防止内存漏洞
length=right.length; //新字符串的长度
sPtr=new char[length+1]; //分配内存
assert(sPtr!=0); //若内存分配失败时中止
strcpy(sPtr, right.sPtr); //拷贝字符串到对象中
}
else
cout<<"Attempted assignment of a String to itself\n";
return *this; //保证能够连续赋值
}
//把右边的操作数余调用函数的对象连接,结果存储在对象中
String &String:: operator+= (const String &right)
{
char *tempPtr=sPtr; //保存临时指针,以便能够删除它
length+=right.length; //新字符串长度
sPtr=new char[length+1]; //分配内存
assert(sPtr!=0); //在内存分配失败时中止
strcpy(sPtr, tempPtr); //新字符串的左边部分
strcat(sPtr, right.sPtr); //新字符串的右边部分
delete []tempPtr; //释放内存
return *this; //保证能够连续调用
}
//测试对象是否为空,为空返回1,否则,返回0
int String:: operator! () const {return length==0;}
//测试s1==s2,若相等,返回1,否则,返回0
int String:: operator== (const String &right) const
{return strcmp(sPtr, right.sPtr)==0;}
//测试s1!=s2,若不相等,返回1,否则,返回0
int String:: operator!= (const String &right) const
{return strcmp(sPtr, right.sPtr)!=0;}
//测试s1>s2,若s1>s2,返回1,否则,返回0
int String:: operator> (const String &right) const
{return strcmp(sPtr, right.sPtr)>0;}
//测试s1<s2,若s1<s2,返回1,否则,返回0
int String:: operator< (const String &right) const
{return strcmp(sPtr, right.sPtr)<0;}
//测试s1>=s2,若s1>=s1,返回1,否则,返回0
int String:: operator>= (const String &right) const
{return strcmp(sPtr, right.sPtr)>=0;}
//测试s1<=s2,若s1<=s2,返回1,否则,返回0
int String:: operator<= (const String &right) const
{return strcmp(sPtr, right.sPtr)<=0;}
//返回对String中某个字符的引用
char &String:: operator[] (int subscript)
{
//首先测试子串是否越界
assert(subscript>=0&&subscript<=length-1);
return sPtr[subscript]; //返回对位置subscript的字符的引用
}
//以对String对象的引用额形式返回
//返回以index开始长度为subLength的子串
String &String:: operator() (int index, int subLength)
{
//保证index没有越界并且子串长度大于等于0
assert(index>=0&&index<length&&subLength>=0);
String *subPtr=new String(" "); //空String对象
assert(subPtr!=0); //保证分配了新的String对象
//计算子串的长度
int size;
if((subLength==0)||(index+subLength>length))
size=length-index+1;
else
size=subLength+1;
//分配子串的内存
delete subPtr->sPtr;
subPtr->length=size;
subPtr->sPtr=new char[size];
assert(subPtr->sPtr!=0); //保证分配了内存
//把子串拷贝到新的String的对象中
int j;
for(int i=index, j=0; i<index+size-1; i++, j++)
subPtr->sPtr[j]=sPtr[i];
subPtr->sPtr[j]='\0'; //新字符串的中止符
return *subPtr; //返回新String对象
}
//返回字符串的长度
int String:: getLength() const
{ return length;}
//重载输出运算符
ostream &operator<< (ostream &output, const String &s)
{
output<<s.sPtr;
return output; //保证能够连续输出
}
//重载输入运算符
istream &operator>> (istream &input, String &s)
{
static char temp[100]; //存储输入的缓冲区
input>>temp;
s=temp; //使用类String的赋值运算符
return input; //保证能够连续输入
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -