1-自己实现string类(赋值运算符函数)

来源:互联网 发布:数据仓库 数据加工 编辑:程序博客网 时间:2024/06/06 01:23
class MyString{public:    MyString(char* = nullptr);    ~MyString();    MyString& operator=(const MyString &);    MyString(const MyString &);    bool operator==(const MyString &);    void showstring();private:    char *m_data;};
#include "MyString.h"MyString::MyString(char *c){    if (c)    {        m_data = new char[strlen(c) + 1];        strcpy(m_data, c);    }    else    {        m_data = new char[1];        *m_data = '\0';    }}MyString::~MyString(){    delete[] m_data;}MyString& MyString::operator=(const MyString &fuzhi){    if (this==&fuzhi)    //避免自我复制    {        return *this;    }    delete[] m_data;    m_data = NULL;    m_data = new char[strlen(fuzhi.m_data) + 1];    strcpy(m_data, fuzhi.m_data);    return *this;}MyString::MyString(const MyString &copy){    m_data = new char[strlen(copy.m_data) + 1];    strcpy(m_data, copy.m_data);}bool MyString::operator==(const MyString &dengyu){    return strcmp(m_data, dengyu.m_data) == 0;}void MyString::showstring(){    cout << this->m_data << endl;}

拷贝构造函数会在以下三种情况下被调用:

1).当用类的一个对象去初始化该类的另一个对象时。

2).如果函数的形参是类的对象,调用该函数,将对象作为函数实参传递给函数的形参时。

3).如果函数的返回值是类的对象,函数执行完成,将返回值返回时。

拷贝构造函数的参数必须为引用
  复制构造函数,本身也是一个函数,如果你给它定义的参数,是一个类型,而不是一个类型的引用,它会首先调用该类型的复制构造函数,重新构造一个新的实例,然而此时的复制构造函数是以值传递的,又要调用复制构造函数,周而复始,一直循环下去了。。。
 
 赋值构造函数参数既可以为引用,也可以为值传递,值传递会多一次拷贝。因此建议赋值构造函数建议也写为引用类型 

复制构造函数的注意事项:
类String的赋值函数比构造函数复杂得多,分四步实现:
(1)第一步,检查自赋值。你可能会认为多此一举,难道有人会愚蠢到写出 a = a 这样的自赋值语句!的确不会。但是间接的自赋值仍有可能出现,例如
(2)第二步,用delete释放原有的内存资源。如果现在不释放,以后就没机会了,将造成内存泄露。
(3)第三步,分配新的内存资源,并复制字符串。注意函数strlen返回的是有效字符串长度,不包含结束符‘\0’。函数strcpy则连‘\0’一起复制。
(4)第四步,返回本对象的引用,目的是为了实现象 a = b = c 这样的链式表达。注意不要将 return *this 错写成 return this 。

如果构造函数中存在动态内存分配,则必须定义拷贝构造函数。否则,会出现“指针悬挂问题”。 

class A{private:             int  *p;public:             A(){p = new int(3);}}

这种情况下,必须最定义拷贝构造函数。否则会造成两个对象的成员指向同一地址。