1. 默认成员函数介绍
2. 默认成员函数分类
函数 | 功能 |
---|---|
构造函数 | 主要完成对成员变量的初始化工作 |
析构函数 | 主要完成对成员变量的清理工作 |
拷贝构造 | 使用同类对象初始化新创建的对象 |
赋值重载 | 把一个对象赋值给另一个对象 |
class date
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
date d1, d2;
d1.Init(2024, 2, 6); // 调用公有成员函数 Init 为对象 d1 内的成员变量初始化
d2.Init(2024, 2, 7); // 调用公有成员函数 Init 为对象 d2 内的成员变量初始化
return 0;
}
1. 构造函数特性
2. 构造函数示例
class date
{
public:
// 构造函数:函数名和类名相同,没有返回值,支持缺省参数
date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
date d1; // 不指定初始值时就用缺省参数初始化对象
date d2(2024, 2, 7); // 在实例化对象的同时顺带就能初始化对象
return 0;
}
1. 为何使用初始化列表
class date
{
public:
date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
_year = 2023; // 成员变量 _year 被初始化了 2 次这咋个整
}
private:
int _year;
int _month;
int _day;
};
2. 初始化列表语法格式
类名(形参列表)
:成员变量1(成员变量 1 的初始值)
,成员变量2(成员变量 2 的初始值)
,成员变量n(成员变量 n 的初始值)
{}
3. 初始化列表示例
class date
{
public:
date(int year = 1, int month = 1, int day = 1)
:_arr((int*)malloc(4 * sizeof(int)))
,_year(year)
,_month(month)
,_day(day)
{
cout << "这是一个构造函数" << endl;
}
private:
int* _arr;
int _year;
int _month;
int _day;
};
4. 初始化列表的特性
1. 概念
2. 格式
~类名()
{
// 函数体
}
1. 析构函数特性
2. 析构函数示例
class stack // 定义一个用于实现栈的类
{
public:
stack(int capacity = 4) // 构造函数
:_array((int*)malloc(4 * sizeof(int)))
, _top(-1)
,_capacity(capacity)
{
cout << "stack(int capacity = 4)" << endl;
}
~stack() // 析构函数:对象的生命周期结束时自动调用析构函数
{
free(_array); // 如果有动态开辟的空间,就不用怕最后会忘记释放了
_top = 0;
_capacity = 0;
cout << "~stack()" << endl;
}
private:
int* _array;
int _top;
int _capacity;
};
1. 拷贝构造概念
在实例化对象时,可以不给初始值让构造函数使用缺省参数,也可以给初始值让构造函数对对象进行初始化。拷贝构造就是用一个现有的同类对象去初始化另一个对象。
拷贝构造函数只有一个形参 (只显示一个形参,this 指针不显示),该形参是对本类类型对象的引用 (一般常用 const 修饰),在用已存在的同类对象创建新对象时自动调用。
2. 拷贝构造语法格式
类名(const 类名& 形参名) // 实际上还是有两个形参,第一个形参为隐藏的 this 指针
{
// 拷贝构造的函数体
}
3. 拷贝构造函数示例
class date
{
public:
// 构造函数
date(int year = 1, int month = 1, int day = 1)
: _day(day)
,_year(year)
,_month(month)
{}
// 拷贝构造函数
date(const date& d)
:_year(d._year)
,_month(d._month)
,_day(d._day)
{}
private:
int _year;
int _month;
int _day;
};
int main()
{
date d1(2024, 2, 8); // 调用构造函数对 d1 进行初始化
date d2(d1); // 调用拷贝构造使用 d1 对 d2 进行初始化
return 0;
}
1. 默认的拷贝构造函数执行的是浅拷贝
2. 深度拷贝构造示例
class stack
{
public:
stack(int capacity = 4) // 构造函数
{
_array = (int*)malloc(sizeof(int) * capacity);
assert(_array);
_top = -1;
_capacity = capacity;
}
stack(const stack& s) // 拷贝构造,this 是 st2,s 是 st1
{
int* tmp = (int*)malloc(s._capacity * sizeof(int));
assert(tmp);
// 将 st1 的 array 中的有效数据拷贝给 st2 的 array
memcpy(tmp, s._array, sizeof(int) * (s._top + 1));
_array = tmp;
_top = s._top;
_capacity = s._capacity;
}
private:
int* _array;
int _top;
int _capacity;
};
1. 运算符重载概述
2. 运算符重载格式
函数返回值类型 operator操作符(形参列表)
{
函数体
}
3. 赋值运算符示例
class date
{
public:
date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
// 将 == 重载成判断两个类类型对象是否相等的运算符
bool operator== (const date& d) // 此处的 this 表示 d1,d 表示 d2
{
return _year == d._year && _month == d._month && _day == d._day;
}
private:
int _year;
int _month;
int _day;
};
4. 运算符重载本质
5. 运算符重载特性
1. 赋值重载功能
2. 赋值重载格式
3. 赋值重载示例
class date
{
public:
date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
date& operator=(const date& d) // this 指针指向 d1,d 表示 d2
{
if (this != &d) // 避免自己给自己赋值
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this; // 返回对 d1 的引用
}
private:
int _year;
int _month;
int _day;
};