问题描述及代码:
#include <iostream>
#include <cassert>
#include <cstring>
using namespace std;
class String
{
private:
char* p;
int len;
public:
String();
String(const char* s);
String(const String& s);
~String();//问题出现在这儿
void show();
friend String operator+(const String& s1,const String& s2);
friend String operator-(String& s1,String& s2);
String& operator=(String s);
};
String::String()
{
len=0;
p=NULL;
}
String::String(const char* s)
{
len=strlen(s);
p=new char[len+1];
strcpy(p,s);
}
String::String(const String& s)
{
len=s.len;
if(p!=NULL)delete []p;
p=new char[len+1];
strcpy(p,s.p);
}
String operator+(const String& s1,const String& s2)
{
String total;
total.len=s1.len+s2.len;
total.p=new char[total.len+1];
strcpy(total.p,s1.p);
strcat(total.p,s2.p);
return total;
}
String operator-(String& s1,String& s2)
{
String s;
char* c1=new char[s1.len+1];
strcpy(c1,s1.p);
int i=s1.len-1;
while(c1[i]==' '&&i>=0)--i;
c1[i+1]='\0';
char* c2=new char[s2.len+1];
strcpy(c2,s2.p);
i=0;
while(i<s2.len&&c2[i]==' ')++i;
int j=0;
while(c2[i]!='\0'&&i<s2.len)
{
c2[j]=c2[i];
++i;
++j;
}
c2[j]='\0';
//s.len=s1.len+s2.len+2;
s.len=strlen(c1)+strlen(c2);
s.p=new char[s.len+1];
strcpy(s.p,c1);
strcat(s.p,c2);
delete c1;
delete c2;
return s;
}
String& String::operator=(String s)
{
if(!this->p)
delete []p;
p=new char(s.len+1);
strcpy(p,s.p);
len=s.len;
return *this;
}
void String::show()
{
cout<<p<<endl;
}
String::~String()
{
delete []p;
}
int main()
{
String str1("123 "),str2(" 456"),str3;
str3=str1+str2;
str3.show();
//str3=str1-str2;
//str3.show();
return 0;
}
运行结果:
这个是在我注释掉了str1-str2之后运行得到的结果。
之前遇到的单步调试直接跳到析构函数的情况没有了,但是并没有修改代码(好奇怪哦。。)
根据贺老师的提示我增加了=的运算符重载,输出正常了,但str1-str2一直得不到正确的结果,而且会出现运行结束的框框。。
ps:
老师给出的=运算符重载的代码是
String &String::operator=(const String &s1)
{
if(!this->p)
delete []p;
p=new char(s1.len+1);
strcpy(p,s1.p);
len=s1.len;
return *this;
}
但我认为这里不用引用类型的返回值比较好,因为前面实现的+运算符重载的返回值不是引用,也就是要生成一个临时的空间来存放结果,这里用引用的话是不是不恰当类?嘿嘿
那个 - 运算符重载的问题目前还在找,可能跟内存有关,如果大家有人知道原因请告诉我。。