UP | HOME

C++ 类中的三巨头:ctor/copy op=/dtor

Table of Contents

1. C++ 中的类

  1. c++ 不同于 c 是它引入了类的机制
  2. 类通过 class 关键字进行定义
  3. 我们可以定义一个自己的 MyString
// 定义一个类
class MyString {

};

// 无参数构造器,后面的括号可以省略,否则 g++ 会给出一些警告,这个写法和函数签名定义歧义
// MyString s1();
MyString s1;

// 检查申请的地址
printf("s1 = %p\n", &s1);

2. 类的生命周期函数

  1. 类可以作为模版来创建实例
  2. 如何创建和销毁就形成了以下几种方法:(只就是 big three)
    1. 构造函数
      • 无参构造函数 (ctor)
      • 拷贝构造函数 (copy ctor)
    2. 拷贝赋值函数 (copy op=)
    3. 析构函数 (dtor)

我们使用之前的例子来定义它,依次定义的结果如下:

class MyString {
public:
    MyString(const char *cstr = 0);
    MyString(const MyString &str);
    MyString& operator=(const MyString &str);
    ~MyString();
    char *get_cstr() const { return m_data; }
private:
    char *m_data;
};

3. 实现类

class MyString {
public:
    MyString(const char *cstr = 0);
    MyString(const MyString &str);
    MyString& operator=(const MyString &str);
    ~MyString();
    char *get_cstr() const { return m_data; }
private:
    char *m_data;
};

// ctor
inline
MyString::MyString(const char *cstr)
{
    if(cstr) {
        m_data = new char[strlen(cstr)+1];
        strcpy(m_data, cstr);
    } else {
        m_data = new char[1];
        *m_data = '\0';
    }
}

// copy ctor
inline
MyString::MyString(const MyString &str)
{
    m_data = new char[strlen(str.m_data)+1];
    strcpy(m_data, str.m_data);
}

// copy op=
MyString& MyString::operator=(const MyString &str)
{
    // 1. 防止 &str 和 this 指向同一个堆空间造成赋值错误
    // 2. 提高执行效率
    if (this == &str) {
        return *this;
    }

    // step1: 删除旧数据
    delete[] m_data;
    // step2: 申请新数据
    m_data = new char[strlen(str.m_data)+1];
    // step3: 拷贝数据
    strcpy(m_data, str.m_data);

    return *this;
}

// dtor
inline
MyString::~MyString()
{
    delete[] m_data;
}

int main (int argc, char *argv[])
{
    MyString s1;
    MyString s2("hello");
    MyString s3(s2);

    printf("s3 = %s\n", s3.get_cstr());
    return 0;
}

4. 重载输出函数 cout

  1. operator<< 必须写成全局函数,因为 ostream 需要访问
  2. operator= 则必需写成成员函数
// 重载输出流函数:必须是全局函数
std::ostream& operator<<(std::ostream& os, const MyString &str)
{
    std::cout << str.get_cstr();
    return os;
}

int main (int argc, char *argv[])
{
    MyString s1;
    MyString s2("hello");
    MyString s3(s2);

    // printf("s3 = %s\n", s3.get_cstr());
    std::cout << s3 << std::endl;
    return 0;
}

Last Updated 2024-04-03 Wed 08:35. Created by Jinghui Hu at 2024-03-30 Sat 00:00.