C++ 类中的三巨头:ctor/copy op=/dtor
Table of Contents
1. C++ 中的类
- c++ 不同于 c 是它引入了类的机制
- 类通过
class
关键字进行定义 - 我们可以定义一个自己的
MyString
类
// 定义一个类 class MyString { }; // 无参数构造器,后面的括号可以省略,否则 g++ 会给出一些警告,这个写法和函数签名定义歧义 // MyString s1(); MyString s1; // 检查申请的地址 printf("s1 = %p\n", &s1);
2. 类的生命周期函数
- 类可以作为模版来创建实例
- 如何创建和销毁就形成了以下几种方法:(只就是 big three)
- 构造函数
- 无参构造函数 (ctor)
- 拷贝构造函数 (copy ctor)
- 拷贝赋值函数 (copy op=)
- 析构函数 (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
operator<<
必须写成全局函数,因为 ostream 需要访问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; }