1、六个默认成员函数
我们创建一个类,如果我们什么都不写,类会自动生成六个默认成员函数;
接下来一个一个了解;
2、构造函数
构造函数是一个特殊的函数,函数名和类名相同,主要是对类的初始化;
class Date { public: // 1.无参构造函数 Date() { } // 2.带参构造函数 Date(int year, int month, int day) { _year = year; _month = month; _day = day; } void Print() { cout << _year << "--" << _month << "--" << _day << endl; } private: int _year; int _month; int _day; };
构造函数的特性:
1.函数名和类名相同,无返回值,构造函数可以重载;
2.构造函数分为无参构造和有参构造;
3.有参构造还可以用缺省值;
例如:
//3.带缺省值的有参构造 Date(int year=2024, int month=4, int day=10) { _year = year; _month = month; _day = day; }
4.无参构造和全缺省构造不能同时调用,会报错,编译器会不知道该调用哪个;
5.如果没有写构造函数,编译器会自动生成一个构造函数,
注意:C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在
类中声明时可以给默认值。
例如:
private: int _year=1; int _month=1; int _day=1;
总结:
1、一般情况下构造函数需要我们自己去写;
2、只有少数情况下可以让编译器自动生成构造函数,类似MyQueue,成员全是自定义类型;
class stack { // }; class MyQueue { private: stack _st1; stack _st2; };
3、析构函数
析构函数在类结束后清理调用的资源;
特性:
1.析构函数名是在类名前加上字符‘~';
2.无参数,无返回值;
3.一个类只有一个析构函数,若没有显式定义,编译器自动生成析构函数,析构函数不能重载;
4.对象生命周期结束后,编译器自动调用析构函数;
5.当类中没有申请资源时,可以不写析构函数,例如Date类,有资源申请时一定要写,否则会造成资源泄露,如stack;
4、拷贝构造
拷贝构造函数:只有一个形参;
特性:
1.拷贝函数也是构造函数的重载,
2.拷贝构造函数参数只能有一个,必须是类类型对象的引用,如果直接传类,编译器会报错,会引发无穷递归;
3.如果没有显式定义,编译器会自动生成默认的拷贝函数,默认的拷贝函数是浅拷贝或者值拷贝,就是不额外开辟空间,遇到一些需要额外开辟空间的类就不适用了;
class Date { public: //有参构造函数 Date(int year=2024, int month=4, int day=11) { _year = year; _month = month; _day = day; } //拷贝构造函数 //d是d1的引用 Date(Date& d) { _year = d._year; _month = d._month; _day = d._day; } void Print() { cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; }; int main() { Date d1; d1.Print(); Date d2 = d1; d2.Print(); return 0; }
注意:
类中如果没有涉及资源申请,可以不写拷贝构造函数,一旦涉及到资源申请,拷贝函数就是要写的,否则就是浅拷贝;
例如:
typedef int DataType; class Stack { public: Stack(size_t capacity = 3) { cout << "Stack(size_t capacity = 3)" << endl; _array = (DataType*)malloc(sizeof(DataType) * capacity); if (NULL == _array) { perror("malloc申请空间失败!!!"); return; } _capacity = capacity; _size = 0; } void Push(DataType data) { // CheckCapacity(); _array[_size] = data; _size++; } void Print() { for (int i = 0; i < _size; i++) { cout << _array[i] << " "; } cout << endl; } // 其他方法... ~Stack() { cout << "~Stack()" << endl; if (_array) { free(_array); _array = NULL; _capacity = 0; _size = 0; } } private: DataType* _array; int _capacity; int _size; }; int main() { Stack d1; d1.Push(1); d1.Push(2); d1.Push(3); d1.Print(); Stack d2 = d1; d2.Print(); return 0; }
该程序会发生崩溃,因为没有写拷贝构造函数,编译器默认的拷贝构造是浅拷贝,导致d1和d2指向同一块空间,调用两次析构函数析构同一块空间,程序崩溃;