string类构造、拷贝构造、赋值、操作符函数实现及注意事项

通过对string类构造、拷贝构造、赋值、操作符函数的实现及调试,可以更加深刻的认识在创建或修改对象内容时的调用关系。下面是简单的实现:

Mystr类:

[cpp]  view plain copy
  1. class Mystr{  
  2. public:  
  3.     Mystr(void);  
  4.     Mystr(const char *str);//加*str=NULL可代替无参构造函数  
  5.     Mystr(const Mystr &other);  
  6.     Mystr & operator=(const Mystr &other);  
  7.     Mystr & operator+=(const Mystr &other);  
  8.     Mystr & operator+(const Mystr &other);  
  9.     ~Mystr(void);  
  10.   
  11.     void print_str();  
  12. private:  
  13.     char *m_data;  
  14. };  

函数定义:

[cpp]  view plain copy
  1. /*构造函数1*/  
  2. Mystr::Mystr(void){   
  3. //  cout<<"constructor 1"<<endl;  
  4.     m_data=new char[1];  
  5.     *m_data='\0';  
  6. }  
  7.   
  8. /*构造函数2*/  
  9. Mystr::Mystr(const char *str){  
  10.     if(str==NULL){  
  11. //      cout<<"constructor 2 NULL"<<endl;  
  12.         m_data=new char[1];  
  13.         *m_data='\0';  
  14.     }  
  15.     else{  
  16. //      cout<<"constructor 2"<<endl;  
  17.         m_data=new char[strlen(str)+1];  
  18.         assert(m_data);  
  19.         strcpy(m_data, str);  
  20.     }  
  21. }  
  22.   
  23. /*拷贝构造函数*/  
  24. Mystr::Mystr(const Mystr &other){  
  25. //  cout<<"copy constructor"<<endl;  
  26.     m_data=new char[strlen(other.m_data)+1];  
  27.     assert(m_data);  
  28.     strcpy(m_data, other.m_data);  
  29. }  
  30.   
  31. /*赋值函数*/  
  32. Mystr& Mystr::operator=(const Mystr &other){  
  33. //  cout<<"operator="<<endl;  
  34.     if(this==&other){//避免自身赋值  
  35. //      cout<<"self"<<endl;  
  36.         return *this;  
  37.     }  
  38.     else{  
  39.         delete [] m_data;  
  40.         m_data=new char[strlen(other.m_data)+1];  
  41.         assert(m_data);  
  42.         strcpy(m_data, other.m_data);  
  43.     }  
  44.     return *this;  
  45. }  
  46.   
  47. /*操作符+=函数*/  
  48. Mystr& Mystr::operator+=(const Mystr &other){  
  49. //  cout<<"operator+="<<endl;  
  50.     int len=strlen(m_data)+strlen(other.m_data);  
  51.     char *t=new char[len+1];  
  52.     assert(t);  
  53.     strcpy(t, m_data);  
  54.     strcat(t, other.m_data);      
  55.   
  56.     if(m_data) delete [] m_data;  
  57.     m_data=t;  
  58.   
  59.     return *this;  
  60. }  
  61.   
  62. /*操作符+函数重载*/  
  63. Mystr& Mystr::operator+(const Mystr &other){  
  64. //  cout<<"operator+"<<endl;  
  65.     int len=strlen(m_data)+strlen(other.m_data);  
  66.     char *t=new char[len+1];  
  67.     assert(t);  
  68.     strcpy(t, m_data);  
  69.     strcat(t, other.m_data);      
  70.     if(m_data) delete [] m_data;  
  71.     m_data=t;  
  72.     return *this;  
  73. }  
  74.   
  75. /*析构函数*/  
  76. Mystr::~Mystr(void){  
  77.     delete [] m_data;  
  78. }  
  79.   
  80. /*普通成员函数*/  
  81. void Mystr::print_str(){  
  82.     cout<<this->m_data<<endl;  
  83. }  

测试用例:

[cpp]  view plain copy
  1. void main(){  
  2.     Mystr s0;//构造1  
  3.     Mystr s1("123abc");//构造2  
  4.     Mystr s2="DEF";//构造2  
  5.     Mystr s3=s2;//拷贝  
  6.   
  7.     s0=s1;//赋值  
  8.     s0+s1;//操作符+  
  9.     s0+=s1;//操作符+=  
  10.     s0.print_str();  
  11.   
  12.     Mystr s4(NULL);//构造2  
  13.     s4=s1+"_XXX";//调用3个函数:构造2(for"_XXX"),操作符+,操作符=  
  14.     s4.print_str();  
  15.     s4=s3+s2;//不同于s4=s1+"_XXX",仅调用2个函数:操作符+,操作符=  
  16.     s4.print_str();   
  17.   
  18.     //s4="aaa"+"bbb";//错误,为什么, ans: +没有重载两个常量操作符  
  19.   
  20.     Mystr s5=s4+"_qqq";//调用3个函数:构造2,操作符+,拷贝  
  21.     s5.print_str();  
  22. }  

实现注意事项:

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 构造函数不能为虚函数,而析构函数可以

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值