1. 构造函数(通常有5类)
1.1 默认构造函数(没有参数)
- 通常没有参数,但它们可以具有具有默认值的参数。
- 如果未在类中声明任何构造函数,编译器将提供隐式默认 inline 构造函数。
- 如果声明了任何非默认构造函数,编译器不会提供默认构造函数:
- 以通过将编译器定义为已删除 来阻止编译器生成隐式 默认构造函数:
1.2 重载构造函数(多个参数)
1.3 拷贝构造函数
- 定义复制构造函数时,还应定义拷贝赋值运算符 (=)
- 可以通过将拷贝构造函数定义为已删除来防止复制对象
String(const String& s) = delete;
// 拷贝构造函数可能具有以下签名之一:Box(Box& other); // Avoid if possible--allows modification of other.Box(const Box& other);Box(volatile Box& other);Box(volatile const Box& other);// Additional parameters OK if they have default valuesBox(Box& other, int i = 42, string label = "Box");
1.4 拷贝赋值构造函数
String& operator=(const String& s)
1.5 移动构造函数
它采用左值引用作为第一个参数,任何其他参数都必须具有默认值。Box(Box&& other);
以一个String类的设计为例:
class String {public:// 0. 默认构造函数 Default constructor,通常没有参数,但可以具有默认值得参数String() {m_str = new char[1];m_str[0] = '\0';m_size = 0;}String() : m_size(0) {m_str = new char[1];m_str[0] = '\0';}// 1. 重载构造函数(多个参数)explicit String(char *str = "") {if (str == nullptr) {m_str = new char[1];m_str[0] = '\0';m_size = 0;// C++中的任何字符串的长度至少为1(即至少包含一个结束符‘\0’)。空字符串也是有效的字符串,它的长度为1,因此他代表一块合法的内存单元而不是NULL。} else {int len = strlen(str);m_str = new char[len + 1];strcpy_s(m_str, len + 1, str);m_size = len;}}// 2. 拷贝构造函数 Copy constructor. - 深拷贝String(const String& s) {m_str = new char[s.m_size + 1];strcpy(m_str, s.m_str);m_size = s.m_size;}// 3. 拷贝赋值构造函数 Copy assignment operator.String& operator=(const String& s) {if (this != &s) { // 检查自赋值delete[] m_str;m_size = s.m_size;m_str = new char[m_size + 1];strcpy(m_str, s.m_str);}return *this; //为了支持链式访问 eg: s3 = s2 = s1;}// 4. 移动构造函数 Move constructor// 采用一个对类类型的右值引用作为参数String(String&& s) noexcept : m_str(nullptr), m_size(0) {m_str = s.m_str;m_size = s.m_size;s.m_str = nullptr;s.m_size = 0;// *this = std::move(s);}// Move constructor的另一种写法String(String&& s) noexcept : m_str(nullptr), m_size(0) {*this = std::move(s);// 如果为你的类同时提供了移动构造函数和移动赋值运算符,// 则可以编写移动构造函数来调用移动赋值运算符,从而消除冗余代码。}// 5. 移动赋值构造函数String& operator=(const String&& s) noexcept {if (this != &s) {delete[] m_str;m_str = s.m_str;m_size = s.m_size;s.m_str = nullptr;s.m_size = 0;}return *this;}~String() {if (m_str != nullptr) {delete[] m_str;}}char *GetPtr() { return m_str; }private:int m_size; // 当前字符串长度char *m_str; // 指向字符串的指针};
2 析构函数
析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
