天天看点

C++面向对象高级开发_极客班_第二节课笔记Big three

Big three

class 有两种 ,一种是带指针的另一种是不带指针的。不带指针的类最典型的就是complex类,而带指针的最典型的就是string类。

带指针的类有很多特性,其中最重要的就是big three.

#ifndef _MYSTRING_
#define _MYSTRING_
class String{
public:
        String(const char* cstr = 0);
        String(const String& r);
        String& operator= (const String&r);
        ~String();
private:
        char* m_data;
};
#endif
           

big three 就是 拷贝构造函数, 拷贝赋值函数以及析构函数。

7.1 构造函数

String::String(const char* cstr = 0)   //构造函数
{
    if(cstr){
        m_data = new char[strlen(cstr) + 1];
        strcpy(m_data, cstr);
    }
    else{
        m_data = new char[1];
        strcpy(m_data, '\0');
    }
}
           
  • 由于带指针的类,类的成员一般都是指针,只有4个字节。它指向的东西存在外部,因此要进行 构造的时候,就要思考如何把指向的外部的东西也进行构造。这样才会有上面一种很标准的写法。

    注意:只有一个”\0”的为空字符串。

7.2 析构函数

String:: ~string()   //析构函数
{
    delete []m_data;
}
           
  • 析构函数的作用在类的对象离开作用域后,会自动调用析构函数。因为如果带指针的类不写析构函数的话,那么当类执行完成后,类就要调用默认被析构掉,而如果类中的指针指向的外部空间没有被析构,就会造成内存泄露。

7.3 拷贝构造函数(copy constructor) (copy ctor)

//要多写
Spring::Spring(const Spring& r) 
{
    m_data = new char[strlen(r.m_data) + 1];
    strcpy(m_data, r.m_data);
}
           

拷贝构造函数适用于

Spring s1("hello");
    Spring s2(s1);
    // Spring s2 = s1;
           

这里由于 s2是第一次出现,s2用s1来进行构造,因此就会调用拷贝构造函数。而拷贝构造函数的调用,从另一个方面解释了,类的不同对象互为友元。因为,s2可以直接调用s1的private数据(兄弟之间互为友元)。

7.4 拷贝赋值函数(copy assignment constructor) (copy op=)

Spring& String::opeator = (const Spring& r)
{
    if(this == &r)          // 检测自我赋值
        return *this;   

    delete []m_data;
    m_data = new char[strlen(r.m_data) + 1];
    strcpy(m_data, r.m_data);
    return *this;
}
           

拷贝赋值函数适用于

Spring s1("hello");
Spring s2;
s2 = s1;
           

s2 已经生成,然后用s1对s2进行赋值的时候会调用拷贝赋值函数。

这个里面特别要注意自我赋值的检查。如果没有自我赋值的检查,碰到自我赋值时就会程序报错。。