上機輔導。學生的一個程序莫名出問題。她是在做一個String類,主要是要實現字符串的連接。?
程序是這樣的,請讀者將其拷到IDE,邊看邊調:
~~~
#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-(const String& s1,const String& s2);
};
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-(const String& s1,const String& s2)
{
char* c1=new char[s1.len+1];
strcpy(c1,s1.p);
int i=s1.len-1;
while(s1.p[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';
String s;
s.len=s1.len+s2.len;
s.p=new char[s.len];
strcpy(s.p,c1);
strcat(s.p,c2);
delete c1;
delete c2;
return s;
}
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;
}
~~~
問題的表現是,`str3.show();`的輸出是幾個莫名的符號!?
我讓她單步跟蹤一下,卻發現無論斷點設在哪里,總是要進到析構函數~String()中去!?
恰其他同學的問題不少,我讓她將這個程序給我發郵件,她不要在此糾纏。我清楚,這里有指針成員。禍水應該與此相關。?
學習越來越深入,學生出問題的程序,常需要仔細閱讀后才能給指導意見了。?
午睡后,打開郵件。將程序拷入IDE,已經注意到了執行`str3=str1+str2;`時,需要有的賦值運算符=的重載。試圖找一下單步時進入~String()時的場景,卻未遂。?
在我的IDE下,`str3=str1+str2;`的結果正常,`str3=str1-str2;`的結果卻異常。野指針的表征,真偽混雜最頭疼。?
重載賦值運算=,在類聲明中加:
~~~
String &operator=(const String& s1);
~~~
實現為:
~~~
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;
}
~~~
先向學生交作業。進入~String()的問題是否還在?暫時放下,待回音。