类string的构造函数、拷贝构造函数和析构函数

来源:互联网 发布:阿里云计算认证考试 编辑:程序博客网 时间:2024/06/15 01:28

引用http://www.cppblog.com/life02/archive/2011/03/07/96085.html  在这个帖子的基础上稍微添加修改了点内容。

String 类的原型如下

class String
{
   public:
          String(const char *str=NULL); //构造函数
          String(const String &other); //拷贝构造函数
          ~String(void); //析构函数
          String& operator=(const String &other); //等号操作符重载

          ShowString();


   private:
          char *m_data; //指针
};


String::~String()
{
    delete [] m_data; //析构函数,释放地址空间
}
String::String(const char *str)
{
    if (str==NULL)//当初始化串不存在的时候,为m_data申请一个空间存放'\0';
     {
        m_data=new char[1];
        *m_data='\0';
     }
    else//当初始化串存在的时候,为m_data申请同样大小的空间存放该串;
     {
        int length=strlen(str);
        m_data=new char[length+1];
        strcpy(m_data,str);
     }
}


String::String(const String &other)//拷贝构造函数,功能与构造函数类似。
{
    int length=strlen(other.m_data);
    m_data=new [length+1];
    strcpy(m_data,other.m_data);
}
String& String::operator =(const String &other) 
{
    if (this==&other)//当地址相同时,直接返回;
        return *this; 
 
    delete [] m_data;//当地址不相同时,删除原来申请的空间,重新开始构造;

    int length= strlen (other.m_data);
    m_data=new [length+1];
    strcpy(m_data,other.m_data);

    return *this; 
}

String::ShowString()//由于m_data是私有成员,对象只能通过public成员函数来访问;

{

         cout<<this->m_data<<endl;

}

      类String拷贝构造函数与普通构造函数的区别是:在函数入口处无需与NULL进行比较,这是因为“引用”不可能是NULL,而“指针”可以为NULL。

      类String的赋值函数比构造函数复杂得多,分四步实现:

      (1)第一步,检查自赋值。你可能会认为多此一举,难道有人会愚蠢到写出a =a 这样的自赋值语句!的确不会。但是间接的自赋值仍有可能出现,例如:

      也许有人会说:“即使出现自赋值,我也可以不理睬,大不了化点时间让对象复制自己而已,反正不会出错!”

      他真的说错了。看看第二步的delete,自杀后还能复制自己吗?所以,如果发现自赋值,应该马上终止函数。注意不要将检查自赋值的if语句

[cpp] view plaincopy
  1. if(this == &other)   

      错写成为

[cpp] view plaincopy
  1. if( *this == other)   

      (2)第二步,用delete释放原有的内存资源。如果现在不释放,以后就没机会了,将造成内存泄露。

      (3)第三步,分配新的内存资源,并复制字符串。注意函数strlen返回的是有效字符串长度,不包含结束符‘\0’。函数strcpy则连‘\0’一起复制。

      (4)第四步,返回本对象的引用,目的是为了实现象a= b =c 这样的链式表达。注意不要将return *this 错写成return this 。那么能否写成returnother 呢?效果不是一样吗?

不可以!因为我们不知道参数other的生命期。有可能other是个临时对象,在赋值结束后它马上消失,那么return other返回的将是垃圾。

7 偷懒的办法处理拷贝构造函数与赋值函数

      如果我们实在不想编写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的缺省函数,怎么办?

      偷懒的办法是:只需将拷贝构造函数和赋值函数声明为私有函数,不用编写代码。

      例如:

[cpp] view plaincopy
  1. class A   
  2. { …  
  3. private:   
  4. A(const A &a); // 私有的拷贝构造函数  
  5. A & operate =(const A &a); // 私有的赋值函数  
  6. };   

      如果有人试图编写如下程序:

[cpp] view plaincopy
  1. A b(a);  // 调用了私有的拷贝构造函数  
  2. b = a;   // 调用了私有的赋值函数  


      编译器将指出错误,因为外界不可以操作A的私有函数。


main()
{
String AD;
char * p="ABCDE";
String B(p);
AD.ShowString();
AD=B;
AD.ShowString();


}

1. strCopy 函数可以为标准库函数 char *strcpy(char *dest, const char *src); 

    需要#inculde <string.h>

2.参考连接:

   高质量C++C编程指南 http://man.chinaunix.net/develop/c&c++/c/c.htm

    字符串函数 http://www.ggv.com.cn/forum/clib/string/strcpy.html

0 0
原创粉丝点击