通过对string类构造、拷贝构造、赋值、操作符函数的实现及调试,可以更加深刻的认识在创建或修改对象内容时的调用关系。下面是简单的实现:
Mystr类:
class Mystr{
public:
Mystr(void);
Mystr(const char *str);//加*str=NULL可代替无参构造函数
Mystr(const Mystr &other);
Mystr & operator=(const Mystr &other);
Mystr & operator+=(const Mystr &other);
Mystr & operator+(const Mystr &other);
~Mystr(void);
void print_str();
private:
char *m_data;
};
函数定义:
/*构造函数1*/
Mystr::Mystr(void){
// cout<<"constructor 1"<<endl;
m_data=new char[1];
*m_data='\0';
}
/*构造函数2*/
Mystr::Mystr(const char *str){
if(str==NULL){
// cout<<"constructor 2 NULL"<<endl;
m_data=new char[1];
*m_data='\0';
}
else{
// cout<<"constructor 2"<<endl;
m_data=new char[strlen(str)+1];
assert(m_data);
strcpy(m_data, str);
}
}
/*拷贝构造函数*/
Mystr::Mystr(const Mystr &other){
// cout<<"copy constructor"<<endl;
m_data=new char[strlen(other.m_data)+1];
assert(m_data);
strcpy(m_data, other.m_data);
}
/*赋值函数*/
Mystr& Mystr::operator=(const Mystr &other){
// cout<<"operator="<<endl;
if(this==&other){//避免自身赋值
// cout<<"self"<<endl;
return *this;
}
else{
delete [] m_data;
m_data=new char[strlen(other.m_data)+1];
assert(m_data);
strcpy(m_data, other.m_data);
}
return *this;
}
/*操作符+=函数*/
Mystr& Mystr::operator+=(const Mystr &other){
// cout<<"operator+="<<endl;
int len=strlen(m_data)+strlen(other.m_data);
char *t=new char[len+1];
assert(t);
strcpy(t, m_data);
strcat(t, other.m_data);
if(m_data) delete [] m_data;
m_data=t;
return *this;
}
/*操作符+函数重载*/
Mystr& Mystr::operator+(const Mystr &other){
// cout<<"operator+"<<endl;
int len=strlen(m_data)+strlen(other.m_data);
char *t=new char[len+1];
assert(t);
strcpy(t, m_data);
strcat(t, other.m_data);
if(m_data) delete [] m_data;
m_data=t;
return *this;
}
/*析构函数*/
Mystr::~Mystr(void){
delete [] m_data;
}
/*普通成员函数*/
void Mystr::print_str(){
cout<<this->m_data<<endl;
}
测试用例:
void main(){
Mystr s0;//构造1
Mystr s1("123abc");//构造2
Mystr s2="DEF";//构造2
Mystr s3=s2;//拷贝
s0=s1;//赋值
s0+s1;//操作符+
s0+=s1;//操作符+=
s0.print_str();
Mystr s4(NULL);//构造2
s4=s1+"_XXX";//调用3个函数:构造2(for"_XXX"),操作符+,操作符=
s4.print_str();
s4=s3+s2;//不同于s4=s1+"_XXX",仅调用2个函数:操作符+,操作符=
s4.print_str();
//s4="aaa"+"bbb";//错误,为什么, ans: +没有重载两个常量操作符
Mystr s5=s4+"_qqq";//调用3个函数:构造2,操作符+,拷贝
s5.print_str();
}
实现注意事项:
1 free或delete 空指针是没问题的, 但野指针或者指向只读内存区的指针会出问题
2 下面第二句会出现内存错误
char *m="111";
delete [] m;//问题在这
m=NULL;
delete [] m;
3 strlen(NULL)的实现中没检查空指针NULL,因此会出内存错误
4 Mystr str;
实现时,不赋初值默认为空字符'\0',不要NULL防止再次访问str时出内存错误,比如strlen(m_data)和访问
5 构造函数无返回值
6 构造函数不能为虚函数,而析构函数可以