所有类创建对象时会自动生成六个默认函数。
但有时候默认函数不能满足需求,可以自己创建对应函数,来代替默认函数。
初始化和清理:构造函数
析构函数
拷贝复制: 赋值重载函数
拷贝构造函数
取地址重载: 普通对象取地址重载
const对象取地址重载
一.构造函数
- 函数名字与类型相同,没有返回值类型。
- 保证每个成员变量都有一个初始值。但默认构造函数赋予变量的初始值是随机值。
- 对象实例化时自动调用构造函数。
- 构造函数可以重载。
- 若类内有显示构造函数,则不调用编译器默认构造函数。
class date {
public:
date(int year, int mouth, int day)
{
_year = year;
_mouth = mouth;
_day = day;
}
date()
{}
private:
int _year;
int _mouth;
int _day;
};
int main(){
date d1(1999,06,11);//调用带参构造函数
date d2;//调用无参构造函数。成员变量为随机值。
}
二.析构函数
完成对类一些资源的清理工作。并不是销毁,销毁任务由编译器完成。
- 析构函数名为 ~+类名
- 无参数,无返回值
- 一个类有且只有一个析构函数,若无显示定义,则调用默认析构函数。
- 对象生命周期结束时,编译器自动调用。
typedef int DataType;
class SeqList {
public:
SeqList(int capacity = 10) {
_pData = (DataType*)malloc(capacity * sizeof(DataType));
assert(_pData);
_size = 0;
_capacity = capacity;
}
~SeqList() {
free(_pData);
_pData = nullptr;
_size = 0;
_capacity = 0;
}
private:
int * _pData;
size_t _size;
size_t _capacity;
};
三.拷贝构造函数
- 是构造函数的重载形式。
- 只有一个参数且必须使用引用传参,用const修饰。使用传值方式会引发无穷递归。
思考:无穷递归的原因:传参会生成临时变量,生成方式为拷贝构造,进而产生无穷递归。
class date {
public:
date(const date&d) {
_year = d._year;
_mouth = d._mouth;
_day = d._day;
}
private:
int _year;
int _mouth;
int _day;
};
- 若没有显示定义,在拷贝构造时为浅拷贝。一些情况下会发生资源崩溃。
浅拷贝:将对象按内存存储按字节完成拷贝
解决方法:
之后更新。
四.运算符重载
c++为了增强代码可读性,引入了运算符重载。
data d1+d2; //若+没有重载则无法通过编译
运算符重载:具有特殊函数名的函数,有参数,有返回值类型。
函数原型:返回值类型 operator运算符 (参数类型);
重载时需注意:
- 不能改变原运算符含义。
- 不能重载无意义符号
.* :: sizeof ?: .
不能重载
全部运算符重载在上上篇博客,日期类运算符重载。
date& operator=(const date& d) { //=重载
_year = d._year;
_mouth = d._mouth;
_day = d._day;
return *this;
}
date operator+(int days) {// +重载
date temp(*this);
int sum = days + _day;
if (sum <= getmouthday(temp._year, temp._mouth)) {
temp._day = sum;
return temp;
}
else {
while (sum > getmouthday(temp._year, temp._mouth))
{
sum -= getmouthday(temp._year, temp._mouth);
if (temp._mouth == 12) {
temp._mouth = 1;
temp._year++;
}
else {
temp._mouth++;
}
}
temp._day = sum;
return temp;
}
}
五.const成员以及取地址操作符重载
1.const修饰的成员函数
表示其隐性参数this指针所指对象无法修改。
- const成员函数内,无法调用其他非const成员对象。
void Display( ) const{
cout << _year << endl ;
// _year ++; 会报错,无法修改成员变量
}
2.const修饰的对象
- 无法修改对象的成员变量
- 无法调用非const类型成员函数
const date d1;
3.取地址与const取地址操作符重载
这两个重载一般不需要显式给出,编译器默认生成就够用了。
class date {
public:
date* operator&() {
return this;
}
const date* operator&()const {
return this;
}
private:
int _year;
int _mouth;
int _day;
};