类的六个默认成员函数
 如果一个类什么都没有称之为空类,但是真的是什么都没有吗?其实并不是,每一个类都会有六个默认成员函数,即使你不写编译器也会成。
构造函数
概念: 构造函数是一个特殊的成员函数,名字与类名相同创建类对象时由编译器自动调用保证每个数据成员都有合适的初始值,并且在生命周期内只调用一次。 特性: 需要注意的是构造函数虽然叫构造,但是主要任务是初始化函数,并不具备开空间创建对象。 其特征如下:
- 与类名相同
- 无返回值
- 构造函数可以重载
- 实例化由编译器自动调用
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
public:
Date()
{
}
Date(int year, int moth, int day)
{
_year = year;
_moth = moth;
_day = day;
}
private:
int _year;
int _moth;
int _day;
};
int main()
{
Date d1;
Date d2(2021, 7, 2);
return 0;
}

当我们没写构造函数,编译器就自动生成一个构造函数,编译器生成的构造函数有点奇怪,它对内置类型不处理,对自定义类型处理,这个处理也仅仅是调用自定义类型的构造函数。 注意:不管是自己写的无参、全缺省或编译器自己生成的都叫默认构造函数。
析构函数
概念:
析构函数: 它与构造函数恰恰相反它不是用于销毁対象的,局部对象的销毁是由编译器完成的,而在编译器销毁对象时,调用析构函数来完成资源的清理。
特性:
- 析构函数名是在类名前面加一个
~ - 无返回值
- 析构函数只能有一个,如果未定义那么编译器会自动生成一个
- 当对象生命周期结束时,编译器会自动调用析构函数来清理
拷贝构造函数
拷贝构造:创建和构造函数一样,但是区别是拷贝构造形参只有一个参数(该形参是类类型对象的引用,一般是const 修饰的引用)在用已存在的类类型对象创建新对象时由编译器自动调用。
特性:
- 构造拷贝也是一个特殊的默认成员函数
- 拷贝构造是构造函数的重载
- 拷贝构造必须传引用否则就会一直永无止境的递归调用
浅拷贝
一般我们用系统自己生成的拷贝构造都是值拷贝,按内存存储的字节序完成拷贝,这种拷贝我们称之为浅拷贝,或值拷贝。
赋值运算符重载
运算符重载
C++为了提高代码的可读性引入了运算符重载,运算重载是一个特殊的函数名的函数,也具有返回值和参数列表跟普通函数类似。
函数原形:返回类型 operator 要重载的运算符(参数列表)
注意:不能通过连接其它符号来创建新的操作符:比如 operator @
- 重载操作符必须有一个返回类型或者枚举类型的操作数
- 用于内置类型的操作符,起含义不能改变,列如:内置的整形+,不能改变其含义
- 作为类成员的重载函数时,其形参看起来比操作数数目少一成员函数的操作符有一个默认的形参
this 限定为第一个形参。 - .*、::、sizeof、?:、.注意这五个运算符不能重载。
使用案列:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
public:
Date()
{
}
Date(int year, int moth, int day)
{
_year = year;
_moth = moth;
_day = day;
}
int operator+(const Date& d)
{
_day += d._day;
return _day;
}
private:
int _year;
int _moth;
int _day;
};
int main()
{
Date d1;
Date d2(2021, 7, 2);
int a = d1 + d2;?
}

赋值运算符重载
我们创建一个类的时候想要拷贝我们有拷贝构造,但是我们想要已创建的对象来拷贝呢?这时我们就得自己写一个赋值重载,但是赋值重载我们不写编译器也会自动生成,赋值重载也是一个默认成员函数。
使用案列:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
public:
Date()
{
}
Date(int year, int moth, int day)
{
_year = year;
_moth = moth;
_day = day;
}
int operator+(const Date& d)
{
_day += d._day;
return _day;
}
Date& operator=(const Date&d)
{
if (this != &d)
{
_year = d._year;
_moth = d._moth;
_day = d._day;
}
}
private:
int _year;
int _moth;
int _day;
};
int main()
{
Date d1;
Date d2(2021, 7, 2);
int a = d1 + d2;
d1 = d2;
return 0;
}

赋值运算符主要有几个特点:
- 参数类型
- 返回值
- 检测自己是否给自己赋值
- 返回
*this - 一个类如果没有显示定义赋值运算符重载,编译器也会生成一个,完成对象按字节序的拷贝。
const成员
const修饰类的成员函数
将const 修饰的类成员函数称之为const 成员函数,const 修饰的成员函数,实际修饰改成员函数隐藏的this 指针,表明在该成员函数中不能对类的任何函数进行修改。
取地址及const取地址操作符重载
这两个默认成员函数一般不用重新定义,编译器默认生成的就够用了,只有特殊情况才需要重载,比如让别人获取到指定的内容。
|