C+笔记七十二:MyString类案例——重载等号和数组操作符

1

前言

在笔记七十一中我们已经搭好了MyString类的基本框架,我们修改Test.cpp文件,添加两行代码:

s4=s2;

s4="ab";

#include

#include"MyString.h"

usingnamespacestd;

intmain()

{

//类定义对象时才调用构造函数

MyString s1;//调用无参构造函数

MyString s2("s2");//调用有参构造函数

MyString s3=s2;//调用拷贝构造函数深拷贝

MyString s4="abcdefg";//调用有参构造函数

s4=s2;//完全复制,指针相等引起二次析构未知bug

s4="ab";//错误未知bug

cout

system("pause");

return0;

}

运行程序,发现可以弹出dos窗口(就是那个显示输出结果的黑框),但是关闭dos窗口时软件卡顿,证明这两行代码在bug,为什么存在bug呢?目前我也不是很清楚,有一点,s4对象在定义时已经申请了一定大小的内存,后面赋值有点不合适,但具体的原因我目前不清楚,知识积累起来再写。

既然我们知道等号操作符这个地方有bug,我们就需要重载等号操作符。

2

重载等号操作符s4=s2

重载时需要分两种情形,第一种s4=s2,等号两侧都是MyString类定义的对象。调用时格式:

s4.operator=(s2)

考虑链式编程,我们需要返回一个引用,因此函数的声明就是:

MyString& operator=(const MyString& str);

注意:一般情况下我们会加const,保证目标对象的安全。

操作符重载函数为:

MyString& MyString::operator=(constMyString& str)

{

//(1)把旧的内存释放掉

if(m_p!=NULL)

{

delete[]m_p;

m_len=0;

}

//(2)根据str分配内存,str是类的对象,至少是空串

m_len=str.m_len;

m_p=newchar[m_len+1];

strcpy(m_p,str.m_p);

return*this;

}

3

重载等号操作符s4="ab"

//重载等号操作符,考虑链式编程

//s4="ab"

//s4.operator=("ab")

//MyString& operator=(const char* str)

//s4的指针已经分配内存空间了,因此需要先把旧的释放掉

MyString& MyString::operator=(constchar* str)

{

//(1)把旧的内存释放掉

if(m_p!=NULL)

{

delete[]m_p;

m_len=0;

}

//(2)根据str分配内存

if(NULL==str)

{

m_len=0;

m_p=newchar[m_len+1];

strcpy(m_p,"");

}

else

{

m_len=strlen(str);

m_p=newchar[m_len+1];

strcpy(m_p,str);

}

return*this;//支持链式编程,返回引用

}

4

MyString类重载数组[]操作符

我们定义一个字符串s4之后,想类似数组一样,输出字符串s4的某个元素,或者修改某个元素,这就需要重载数组操作符[],因为要修改字符串的某个元素,也就是说字符串数组当左值,因此需要返回一个引用。

//s4[index]

//s4.operator[](int index)

//char& operator[](int index)

完整程序:

MyString.h

#pragmaonce

classMyString

{

public:

//无参构造函数,定义一个空串

MyString(void);

//有参构造函数

MyString(constchar*p);

//拷贝构造函数

MyString(constMyString& s);

//析构函数

~MyString(void);

public:

//等号操作符重载函数s4=s2;

MyString&operator=(constMyString& str);

//等号操作符重载函数s4="ab";

MyString&operator=(constchar* str);

//重载[]操作符

char&operator[](intindex);

private:

intm_len;//储存字符串的长度

char*m_p;//指向字符串所在内存的首地址

};

MyString.cpp

#define_CRT_SECURE_NO_WARNINGS

#include

#include"MyString.h"

//无参构造函数,定义一个空串

MyString::MyString(void)

{

m_len=0;

m_p=newchar[m_len+1];

strcpy(m_p,"");

}

//有参构造函数

MyString::MyString(constchar*p)

{

if(NULL==p)

{

m_len=0;

m_p=newchar[m_len+1];

strcpy(m_p,p);

}

else

{

m_len=strlen(p);

m_p=newchar[m_len+1];

strcpy(m_p,p);

}

}

//拷贝构造函数

MyString::MyString(constMyString& s)

{

m_len=s.m_len;

m_p=newchar[m_len+1];

strcpy(m_p,s.m_p);

}

//析构函数

MyString::~MyString(void)

{

if(m_p!=NULL)

{

delete[]m_p;

m_p=NULL;

m_len=0;

}

}

//重载等号操作符,考虑链式编程

//s4=s2

//s4.operator=(s2)

//MyString& operator=(const MyString& str)

//s4的指针已经分配内存空间了,因此需要先把旧的释放掉

MyString& MyString::operator=(constMyString& str)

{

//(1)把旧的内存释放掉

if(m_p!=NULL)

{

delete[]m_p;

m_len=0;

}

//(2)根据str分配内存,str是类的对象,至少是空串

m_len=str.m_len;

m_p=newchar[m_len+1];

strcpy(m_p,str.m_p);

return*this;

}

//重载等号操作符,考虑链式编程

//s4="ab"

//s4.operator=("ab")

//MyString& operator=(const char* str)

//s4的指针已经分配内存空间了,因此需要先把旧的释放掉

MyString& MyString::operator=(constchar* str)

{

//(1)把旧的内存释放掉

if(m_p!=NULL)

{

delete[]m_p;

m_len=0;

}

//(2)根据str分配内存

if(NULL==str)

{

m_len=0;

m_p=newchar[m_len+1];

strcpy(m_p,"");

}

else

{

m_len=strlen(str);

m_p=newchar[m_len+1];

strcpy(m_p,str);

}

return*this;//支持链式编程,返回引用

}

//重载数组小标[]操作符

//s4[i]

//s4.operator[](int i)

//char& operator[](int i)

char& MyString::operator[](intindex)

{

returnm_p[index];//可以作为左值,返回引用

}

Test.cpp

#include

#include"MyString.h"

usingnamespacestd;

intmain()

{

//类定义对象时才调用构造函数

MyString s1;//调用无参构造函数

MyString s2("s2");//调用有参构造函数

MyString s3=s2;//调用拷贝构造函数深拷贝

MyString s4="abcdefg";//调用有参构造函数

s4=s2;

s4="abcde";

cout

s4[2]='f';

cout

cout

system("pause");

return0;

}

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180621A0HG8P00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券