目录
类的默认成员函数
一个类中若没有成员则称为空类。
任何一个类都会生成6个默认成员函数:
1. 构造函数 // 初始化
2. 拷贝构造函数 // 使用同类对象初始化创建对象
3. 析构函数 // 清理
4. 赋值操作符重载 // 将一个对象赋值给另一个对象
5. 取地址操作符重载 // 普通对象取地址
6. const修饰的取地址操作符重载 // const对象取地址
构造函数
概念:
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员都有一个合适的
初始值,并且在对象生命周期内只调用一次。
特性:
1. 函数名与类名相同
2. 无返回值
3. 对象构造(实例化时) 编译器自动调用对应的构造函数
4. 构造函数可以重载
5. 如果类中没有显示定义构造函数,则编译器会自动生成一个默认的构造函数,一旦用户显示定义,编译器将不再生
成;(若有无参的对象可以自己显示定义 或在有 参的构造函数添加缺省值<缺省构造函数>)
注:无参与缺省只能存在一个
6. 一个 无参的构造函数和缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个;
7. 默认的构造函数会对自定义类型成员调用它的默认成员函数;
8. 成员变量命名风格:成员变量前加 “_” 或 其它前缀。
析构函数
概念:
与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作。
typedef int DataType;
class SeqList
{
DataType *_array;
size_t _size;
size_t _capacity;
public:
SeqList(size_t capacity = 10)
{
_array = (DataType*)malloc(sizeof(DataType) * capacity);
if (nullptr == _array)
{
assert(0);
}
_capacity = capacity;
_size = 0;
}
~SeqList()
{
if (_array)
{
free(_array);
_array = nullptr;
_capacity = 0;
_size = 0;
}
}
void PushBack(const DataType data)
{
_array[_size++] = data;
}
void PopBack()
{
--_size;
}
};
void TestFunc()
{
SeqList s;
s.PushBack(1);
s.PushBack(2);
s.PushBack(3);
s.PopBack();
}
int main()
{
TestFunc();
return 0;
}
特性:
1. 析构函数名是在类名前加“~”;
2. 无参数无返回值(不能重载)
3 . 一个类有且只有一个析构函数。若未显示定义则系统会自动生成默认的析构函数
4. 对象生命周期结束时,C++编译系统自动调用析构函数。
5. 编译器生成的默认析构函数,对会自定类型成员调用它的析构函数。
为什么构造函数有参数而析构函数没有参数?
析构函数是对象销毁时由编译器来调,对象将要消亡。
拷贝构造函数
在创建对象时,为了创建一个与一个对象一模一样的新对象 ----> 拷贝构造函数
概念:
只有单个形参,该形参对本类类型对象的引用(一般常用const修饰,防止调用时修改原来成员变量),在已存在的类类型对象创建新对象时由编译器自动调用。
为什么一定要传递引用?
若传值,需要创建一个临时对象Date(const Date d)来接收,然后又传值引发对象的拷贝,这样下去将会无限调用。
特征:
1. 拷贝构造函数是构造函数的一个重载形式
2. 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用
3. 若未显示定义,系统生成默认的拷贝构造函数。默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷 贝,或值拷贝。
既然系统会自动生成拷贝构造,为什么还要有自定义拷贝构造呢?
typedef int Datatype;
class SeqList
{
Datatype *_array;
size_t _size;
size_t _capacity;
public:
SeqList(size_t capacity = 10)
{
_array = (Datatype*)malloc(sizeof(Datatype)*capacity);
if (nullptr == _array){
assert(0);
}
_capacity = capacity;
_size = 0;
}
~SeqList()
{
if (_array){
free(_array);
_array = nullptr;
_capacity = 0;
_size = 0;
}
}
void PushBack(const Datatype data)
{
_array[_size++] = data;
}
void PopBack()
{
--_size;
}
};
int main()
{
SeqList d1;
SeqList d2(d1);
return 0;
}
调用上面程序,若采用默认拷贝构造的方式就会报错。所以在涉及资源管理时应自定义拷贝构造函数。