重新初始化字符串对象时发生崩溃

时间:2014-12-16 14:58:01

标签: c++ string

请求您深入了解下面的字符串类程序

class String{
private: int len;
         int size;
         char *p;
public:  
     int getlen()
     {
         return len;
     }
     int getsize()
     {
         return size;
     }
     char* getp()
     {
         return p;
     }
     String(char *p1=0)
     {
         cout<<"constructor called"<<endl;
         if(p1!=0)
         {
            len=strlen(p1);
            size=len+1;
            p=new char(sizeof(char)*(size));
            strncpy(p,p1,size);
         }
         else
         {
             len=size=0;
             p="";
         }
     }
     String(String &s1)
     {
         cout<<"copy constructor called"<<endl;
         if(&s1!=this)
         {
             cout<<"copy constructor called"<<endl;
             len=s1.getlen();
             size=len+1;
             p=new char(sizeof(char)*(size));
             //char *d=s1.getp();
             strncpy(p,s1.getp(),size);
         }
     }
     void display()
     {
         cout<<"string len="<<len<<endl;
         cout<<"string size="<<size<<endl;
         cout<<"string name="<<p<<endl;
     }
     ~String()
     {
         cout<<"destructor called"<<endl;
         if(strlen(p) >= 1)
         {
            cout<<"111"<<endl;
            delete []p;
         }
         //cout<<"destructor finished"<<endl;
     }
};
int main(int argc, char *argv[])
{
  String s1;
  String s2("hello");
  s1.display();
  s2.display();
  s2=String("Hello World");
  s2.display();
  return 0;
}

请查看重新初始化行

     s2=String("Hello World");

String(&#34; Hello World&#34;)将创建一个临时String对象,它应该调用赋值运算符。由于编译器的默认赋值运算符会执行浅复制,因此在临时String对象超出范围后,String类中存在的char指针将变为NULL。

我试图重载赋值运算符,如下所示

 String& operator =(String &s1)
 {
     cout<<"operator = called"<<endl;
     if(&s1!=this)
     {
         len=s1.len;
         size=s1.size;
         if(strlen(p)>=1)
              delete p;
         p=new char(sizeof(char)*size);
         strncpy(p,s1.getp(),size);
     }
     return *this;
  }

但是它给错误'operator ='不匹配(操作数类型是'String'和'String')   S2 =字符串(&#34;世界&#34);

请求您在更正&#39; operator =&#39;之后编译程序,因为我怀疑复制构造函数可能会给出任何错误..

提前致谢..

1 个答案:

答案 0 :(得分:5)

这一行存在一个问题:

p=new char(sizeof(char)*(size));

您需要使用方括号:

p=new char[sizeof(char)*(size)];
          ^                   ^

其次,对于复制构造函数和赋值运算符,参数类型应为const - 限定引用,即const String&,而不仅仅是String&。此外,作为良好实践,任何不修改任何成员变量的方法(例如displaygetp)都应在函数声明的末尾有const(即就在{之前。