1.构造函数:
class Date
{
public:
Date()
{
_year = 0;
_month = 0;
_day = 0;
}
Date(int year,int month,int day)
{
_year = year;
_month = month;
_day = day;
}
private:
//会生成默认构造
//对内置类型不做处理
int _year;
int _month;
int _day;
}
构造函数其实就是相当于一个自动调用的初始化,如果我们开始使用Date,那么它将自己给其赋值
我们接下来要注意几个点
为什么调用无参构造函数我们不加括号,也就是的d1后面为什么不加(),因为这很难与自己的函数声明区分开,加了括号,此时该函数没有参数,并且按照声明来看我们就是返回了一个Date 类型,但是我们这时候就是调用一个构造函数;
写了两个构造函数,一个有参一个无参,这有没有问题,其实是有的;
int main()
{
Data d1;
return 0;
}
这个时候我们该调用哪个呢,调用无参和有参都可以,所以在这种情况下,两者是不能同时存在的既然如此我们就写那个有参的,因为都是能使用,所以我们直接写一个全缺省。
class Date
{
public:
private:
//会生成默认构造
//对内置类型不做处理
int _year=1;
int _month=0;
int _day=0;
}
2:
析构函数:析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
typedef int DataType;
class Stack
{
public:
Stack(size_t capacity = 3)
{
_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++;
}
~Stack()//析构函数
{
if (_array)
{
free(_array);
_array = NULL;
_capacity = 0;
_size = 0;
}
}
private:
DataType* _array;
int _capacity;
int _size;
};
特性5:如果没有定义析构函数,那么编译器就会自己生成一个,那为什么我们还要自己写一个,那还有有不同的情况啊,比如链表,那不得一个一个释放啊。
总结:
<1>.有资源需要清理,就要写析构,比如:Stack,List
<2>.两种情况不用写:a.无资源清理的 b.内置类型成员没有资源需要清理的,剩下的都是自定义的成员,如MyQueue,就是用栈实现队列,栈里面自己写了,就可以自己调用.
3.拷贝函数
typedef int DataType;
class Stack
{
public:
Stack(size_t capacity = 3)
{
_array = (DataType*)malloc(sizeof(DataType) * capacity);
if (NULL == _array)
{
perror("malloc申请空间失败!!!");
return;
}
_capacity = capacity;
_size = 0;
}
Stack(const Stack& d)
{
_array = (DataType*)malloc(sizeof(DataType) * d._capacity);
if (_array == NULL)
{
perror("fail");
}
_size = d._size;
_capacity = d._capacity;
}
void Push(DataType data)
{
// CheckCapacity();
_array[_size] = data;
_size++;
}
// 其他方法...
~Stack()//析构函数
{
if (_array)
{
free(_array);
_array = NULL;
_capacity = 0;
_size = 0;
}
}
private:
DataType* _array;
int _capacity;
int _size;
};
其实拷贝函数是构造函数中的一种;
如果按照下面的写法为什么会引发递归呢:
int main()
{
Stack s1;
Stack s2=s1;
return 0;
}
首先要知道,自定义类型拷贝时候会调用拷贝函数
我们给s2进行拷贝构造的时候,它是一个自定义类型 Stack ,因为函数栈帧上我们知道,传值调用的时候形参和实参并不是一块空间,把实参的内容拷贝到形参,所以给s2拷贝时候先得给d拷贝了。我们d也是自定义类型会引发一个拷贝,但是传的s1不是实参,为了和实参一样,这一次的d他又进行了拷贝构造,拷贝构造时候又出现了d,可惜还不是实参,这样一直进行递归。如果我们用的是引用,调用拷贝函数的时候,第一次就是s1的实参,直接就可以使用,把s1的实参直接拷贝给d,d再给s2使用