1.构造函数(不属于默认构造):
在之前的代码中,你是否会感觉下面这样的代码有点多余,每次都需要进行一次初始化。
class date{
public:
void init(int year,int month,int day) {
year = year;
month = month;
day = day;
}
private:
int year_;
int month_;
int day_;
};
}
c++为我们提供了一种在生成对象的时候直接进行一次初始化的构造函数(我们自己选择写的情况,不写会直接使用默认构造,后续说明)。如下图:
要注意的是,这个构造函数的名字和对象的名字是一样的,并且不会有返回值,所以也不用去写返回值的类型,编译器直接为我们优化了,当然也是支持函数重载的,如下:
但是在不传入参数的时候就会因为编译器不知道选哪个函数出现问题,如下
解决方法就是直接使用缺省参数的形式进行设置构造函数。
2.默认构造
全缺省构造,无参构造,自定义类型的自动构造均属于默认构造。
对于内置类型的成员变量,例如:int,char...
对于自定义类型的成员变量,例如:strcut class
对于内置类型的它没有要求太多,如果没有自定义的构造,那么就是生成随机值,但是对于自定义的就需要有自定义的构造函数去初始化,如果没有就会出现报错(需要用后续的知识解决)。
对于自定义的构造函数,本文以两个栈实现一个队列的初始化进行说明
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int datatype;
class ST {
public:
ST() {
datatype* tmp = (datatype*)malloc(sizeof(datatype) * 4);
if (tmp == NULL) {
printf("init fail:%s\n", strerror(errno));
}
else {
data = tmp;
capacity = 4;
size = 0;
}
}
void if_full() {
if (capacity == size) {
datatype* tmp = (datatype*)realloc(data,capacity * 2 * sizeof(datatype));
if (tmp == NULL) {
printf("if_full fail:%s\n", strerror(errno));
}
else {
data = tmp;
capacity *= 2;
}
}
}
void stackpush( datatype x) {
if_full();
data[size] = x;
size++;
}
int stacktop() {
return data[size - 1];
}
void stackpop() {
size--;
}
int stacksize() {
return size;
}
bool stackempty() {
if (size == 0)
return true;
else
return false;
}
void stackdel() {
free(data);
size = 0;
capacity = 0;
}
private:
datatype* data;
int size;
int capacity;
};
class MyQueue {
ST st1;
ST st2;
};
class date {
public:
/*void init(int year,int month,int day) {
year = year;
month = month;
day = day;
}*/
//date() {
// year_= 1;
// month_ = 1;
// day_= 1;
//}
//date(int year=1,int month=2,int day=3) {
// year_ = year;
// month_ = month;
// day_ = day;
//}
void print() {
cout << year_<<' ' << month_<<' ' << day_;
}
private:
int year_;
int month_;
int day_;
};
int main() {
ST st1;
ST st2;
MyQueue q1;
}
主要看这里,MyQueue这个类根本没有自己写构造,但是最后出现了这样的效果:
从图中可以看出,自动进行了初始化。
3.析构函数
在上面那个代码中有这么一个函数
void stackdel() {
free(data);
data=nullptr;
size = 0;
capacity = 0;
}
这个函数用于释放掉里面申请的空间。(后面那两个是顺便清理),不是申请的空间程序结束自己就会销毁的。
析构函数可以做到这一点。
注意的事项:
~ST() {
free(data);
size = 0;
capacity = 0;
}
1.使用的方式是对象名前面加个~即可,和构造函数很类似。
2.析构函数会在对象的生命周期结束的时候自动调用。(越往后定义的对象越早被析构,如果有static修饰会使得该对象在程序结束的时候才销毁,会最后才析构)
3.与构造函数类似,q1会直接去调栈的析构函数(你就算自己写一个在Myqueue里面也是没用的,会全都调用,Myqueue中的会调用,栈里面的也会调用)