1.构造函数
我们在用类实例化处对象后总是要自己对它进行初始化,有时还会忘记初始化,这样会造成不必要的麻烦。构造函数可以实现在类实例化出对象后自动初始化成员变量。
1.概念
构造函数是一个特殊的成员函数,名字与类名相同,类实例化时由编译器自动调用,保证每个数据成员都有 一个合适的初始值,并且在对象的生命周期内只调用一次。
2.特性和使用
1.构造函数有形参,函数名必须和类名相同。
2.构造函数没有返回值。
3.构造函数只能在类当中定义,不能在类中声明类外定义。它的普通的函数有区别。
3.构造函数可以重载。(根据形参不同调用不同函数)
4.自动调用。(在实例化对象时)
5.构造函数编译器会默认生成,用户也可以自己按照规则定义构造函数,当用户自己定义构造函数后编译器就不会执行自己的默认构造函数而是执行用户的。
6.默认构造函数只能有一个。即:无参数的和全缺省的构造函数不能同时存在。
7.编译器的默认构造函数不会对内置类型的变量(int、char、float等)初始化,对于用户自定义的类型会调用它的构造函数初始化它。
析构函数
1.概念
在对象被系统销毁时,编译器会调用析构函数,来完成资源的清理,比如清理掉malloc出来的空间。
2.特性
1.析构函数无形参,也无返回值。
2.在类名前加~构成析构函数
3.一个类只能定义一个析构函数。编译器有自己的析构函数,当用户未定义,编译器才会调用自己的析构函数。
4.当对象的生命周期结束时,编译器会自动调用析构函数清理资源。
5.与构造函数相同,编译器自己的析构函数不会对内置类型处理,只会通过调用自定义对象的析构函数来处理自定义类型。
class Stack
{
public:
Stack(int capacity = 4)
{
_a = (int*)malloc(sizeof(int)*capacity);
_size = 0;
_capacity = capacity;
}
~Stack()
{
free(_a);
_size = 0;
_capacity = 0;
}
private:
int *_a;
int _size;
int _capacity;
};
3.析构函数调用顺序
析构函数的调用顺序是和构造函数调用顺序完全相反的。
构造函数调用顺序:
1.全局变量
2.静态变量
3.局部变量
例如:

C c;
void main()
{
A*pa=new A();
B b;
static D d;
delete pa;
}
pa、b、c、d四个变量构造顺序是:c、d、pa、b,析构顺序是:a、b、d、c。
解释:上述例子中,pa先被delete因此先调用析构函数,剩下三个变量c是全局变量,d是静态变量,b是局部变量,因此它们调用构造函数的顺序是 c、d、b,故析构顺序是b、d、c。综上析构顺序为 a、b、d、c。
3.拷贝构造函数
概念
拷贝构造函数,函数名和类名相同没有返回值,有形参,允许定义对象时复制出一个和其它对象一模一样的对象。
特性
1.拷贝构造函数是构造函数的一个重载形式
2.拷贝构造函数在赋值的时候,传引用,否则会引发无线递归传参。
3.类赋值的时候调用的是拷贝构造函数
4.c++编译器默认提供的拷贝构造函数,只能进行值拷贝这样的浅拷贝。像复制链表这样需要开辟空间在复制值这种深拷贝是不可以的,需要用户自己定义。
class Date
{
public:
Date(int year = 2000; int month = 1; int day = 1)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
// 拷贝构造函数定义
Date(const Date& d)//只能传引用
{
_year = d._year;
_month = d._month;
_day = d._day;
}
private:
int _year;
int _month;
int _day;
};
//使用拷贝构造函数
Date d1 = d2 ; // 或 Date d1(d2);
4.赋值运算符重载
c++默认允许自定义运算符,使对象可以像 内置类型的变量一样进行运算。
概念
返回值 operator 操作符 形参
注意
1.重载后的运算符应保留原有含义。例如 + 重载后应还用于加法,而不能用于减法
2.运算符重载不改变运算符的优先级。
3.以下运算符不能被重载:. 、 .*、 ? 、 :: 、 sizeof。
4.() 、[]、->、=只能重载为类中的函数,不能重载为全局函数。
// 赋值运算符重载
// d1 = d2
Date& operator = (/*Date *this */const Date& d) //参数的个数就是运算符操作数的个数,这里因为有个隐含的 this针
{
//可认为参数两个,函数内我把this 指针写出来了,它是可以不用写的。
this->_year = d._year;
this->_month = d._month;
this->_day = d._day;
return d;
}
//赋值运算符使用
Date d1;
d1 = d2; // 或 d1(d2);