请求您深入了解下面的字符串类程序
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;
}
Run Code Online (Sandbox Code Playgroud)
请查看重新初始化行
s2=String("Hello World");
Run Code Online (Sandbox Code Playgroud)
String("Hello World")将创建一个临时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;
}
Run Code Online (Sandbox Code Playgroud)
但它给出的错误是'operator ='不匹配(操作数类型是'String'和'String')s2 = String("World");
请求您在更正'operator ='后编译程序,因为我怀疑复制构造函数可能会给出任何错误..
提前致谢..
一个问题是这一行:
p=new char(sizeof(char)*(size));
Run Code Online (Sandbox Code Playgroud)
你需要使用方括号:
p=new char[sizeof(char)*(size)];
^ ^
Run Code Online (Sandbox Code Playgroud)
其次,对于您的复制构造函数和赋值运算符,参数类型应该是const-qualified references,aka const String&,而不仅仅是String&.此外,作为良好实践,任何不修改任何成员变量(例如display或getp)的方法都应该const在函数声明的末尾(即在...之前{).