C++学习笔记(侯捷video 7-13)

一、Big three(拷贝构造、拷贝赋值、析构函数)(video7)

Big three指三个特殊函数,分别是拷贝构造函数、拷贝赋值和析构函数。

什么时候需要拷贝构造、拷贝赋值、析构函数:

  当类中的数据是指针时,例如string类中保存字符串使用char *,那么就不能直接使用编译器给的默认Big three。因为默认的函数是按字节拷贝的,这样拷贝后的对象中的指针指向的位置和被拷贝的对象一样,这样不是真正的拷贝。

class mystring {
public:
    //普通构造函数
    mystring(const char* chr = 0);
    //拷贝构造函数
    mystring(const mystring& mstr);
    //析构函数
    ~mystring();

    //拷贝赋值
    mystring& operator = (const mystring& mstr) {
        //检测是否为自我赋值
        if (this == &mstr) {
            return *this;
        }
        //先将已有的空间释放,否则会内存泄漏
        delete[] mychar;
        //创建新的空间,大小和mstr.mychar指向空间一样大
        mychar = new char[strlen(mstr.mychar) + 1];
        //赋值内容
        strcpy(mychar, mstr.mychar);
        //返回等号左边的mystring对象,以防连续赋值
        return *this;
    }
private:
    //变量是指针,必须实现拷贝赋值和拷贝构造
    char * mychar;

};

inline mystring::mystring(const char* chr) {
    //判断传入的指针是否为空(或默认为空)
    if (chr) {
        //如果不为空,则按chr的大小分配空间,并让mychar指向该空间
        mychar = new char[strlen(chr) + 1];
        //将chr的数据复制到mychar指向的空间中
        strcpy(mychar, chr);
    //如果指针为空
    }else {
        //创建一个大小为1的空间
        mychar = new char[1];
        //只保存一个\0
        *mychar = '\0';
    }
}
inline mystring::mystring(const mystring& mstr) {
    //分配一个和mstr.mychar字符串一样大的空间,并让mychar指向该空间
    mychar = new char[strlen(mstr.mychar) + 1];
    //将内容复制到mychar指向的空间中
    strcpy(mychar, mstr.mychar);
}
inline mystring::~mystring() {
    //当对象生命周期要结束的时候,必须清理内存(堆空间),否则会内存泄漏
    delete[] mychar;
}

在上述代码中,拷贝构造函数做的事情实际上是深拷贝,而默认的拷贝构造函数做的事情是浅拷贝(只复制mstr.mychar指针的4byte到mychar中)。如下图所示:

代码中,以下部分非常重要:

//检测是否为自我赋值
if (this == &mstr) {
    return *this;
}

如果this和mstr是同一个对象,那么如果没有自我赋值的检测,可能会导致程序出错。

因为我们在拷贝数据之前,第一步就是先delete[] mychar,那么也就是删除了mstr.mychar指向的空间。

第二步我们要参照mstr.mychar指向空间的大小来开辟空间就会出问题,更别提复制其中的内容。

所以,自我赋值检测非常重要。

二、为mystring类添加<<重载函数

//定义成员方法,获取mychar指针,不修改数据,加上const
inline char * mystring::get_c_str() const {
    return this->mychar;
}
//重载操作符<<,使可以直接cout<<mystring_obj;
inline ostream& operator << (ostream& os, const mystring& mstr) {
    os << mstr.get_c_str();
    return os;
}

三、

猜你喜欢

转载自www.cnblogs.com/leokale-zz/p/11080516.html
今日推荐