构造函数:
这里的构造函数本质上就是你在C语言中的初始化函数,用于各种类型的初始化,既可以适用于内置类型,同样适用于自定义类型。
模板:
类名 (参数)——
{
}
比如
class stack
{
public:
stack(int capacity = 4)
{
_capacity = capacity;
num = 0;
_arr = (int*)malloc(sizeof(int)* _capacity);
}
private:
int *_arr;
int _num;
int _capacity;
};
其中构造函数是这一段,
stack(int capacity = 4)
{
_capacity = capacity;
num = 0;
_arr = (int*)malloc(sizeof(int)* _capacity);
}
可以观察到的是,这个构造函数没有返回类型!!cpp中使用这个方法来确认出这个是构造函数,以后只要你使用了这个类型时,系统就会自动执行这个构造函数,即初始化!
如果你没有写的时候,系统就会调用系统的默认构造函数,如果你的成员时内置类型,根据编译器的区别,有的会帮你初始化成为0,有的就是随机值。但对于成员是自定义类型的,你不写构造函数就会报错。
默认构造函数指的是不用参数就可以调用的构造函数,而并非是指系统默认的构造函数!!!系统默认的构造函数时默认构造函数的一部分。三个默认构造函数只能同时存在一个,否则会出现识别错误。
2.析构函数:
讲完了构造函数——对应C语言中的初始化函数,现在就来讲析构函数——对应函数中的销毁函数。
~类名()——在类名前加一个 ~ 就是析构函数,同样会自动执行,执行时间为:该类型的变量生命周期的结束时刻。对于多个同类型的变量同时销毁,依次执行晚定义变量的销毁函数。
{
};
这里同样存在这一个你没写的问题,如果你没写,系统同样会执行一个自动销毁函数,如果你申请了内存,没写,系统默认的析构函数没帮你释放内存,就会造成内存泄漏!!
所以只要你在前面构造函数中申请了资源就要写,反之,可以不用写。
e.g
class stack
{
public:
stack(int capacity = 4)
{
_capacity = capacity;
num = 0;
_arr = (int*)malloc(sizeof(int)* _capacity);
~stack()
{
free(_arr);
_num = _capacity = 0;
}
private:
int *_arr;
int _num;
int _capacity;
};
这一段就是析构函数
~stack()
{
free(_arr);
_num = _capacity = 0;
}
因为很明显的是我们在构造函数中申请了内存,所以我们在这里就要写一个析构函数
3.拷贝构造函数
从名字可以看出这个是一个构造函数,一个特殊的构造函数!这个的应用差不多可以想成strncpy/strcpy/memcpy作用相似,是把一个已经存在的变量用来初始化另一个变量。
结构:
类名(const 类名&名称)——这里讲究很多,比如为什么要用引用,不用行不行?这个问题就会引出更多的问题,如果不行,为什么?涉及到传参的本质。这里要是讲明白就会太浪费篇幅,我会单独另开一篇文章来仔细分析这个现象。
比如
class stack
{
public:
stack(int capacity = 4)
{
_capacity = capacity;
num = 0;
_arr = (int*)malloc(sizeof(int)* _capacity);
stack(const stack& st)
{
_capacity = st._capacity;
_num = st._num;
_arr = (int*)malloc(sizeof(int)*_capacity);——这里不能直接 _arr = st._arr;因为这相当于把你开辟的空间的地址直接给他了,后面这两个变量进行操作时会相互干扰!!所以我们单独申请一片空间
memmove(_arr,st._arr,sizeof(int)*_capacity);
}
~stack()
{
free(_arr);
_num = _capacity = 0;
}
private:
int *_arr;
int _num;
int _capacity;
};