C++ 类成员函数全家桶
RAII
Resource Acquisition Is Initialization,资源获取即初始化
这是一种解决资源管理问题的方法,将资源的有效期与持有资源的对象的生命期严格绑定,由对象的构造函数完成资源的分配,由析构函数完成资源的释放
C++借助构造函数和析构函数,解决了传统的 malloc & free 和 new & delete 管理资源方法无法有效应对复杂资源管理场景的问题
对于资源管理需求,无GC机制的C++语言提供了基于析构函数的RAII方法和智能指针,有GC机制的Java语言提供了垃圾回收机制(Garbage Collection,GC).需要注意的是,虽然它们都能避免发生内存泄漏问题,但实现原理并不相同.
首先,从语言的设计角度来说,C++的设计应用场景要求其对代码的执行过程做到可控,RAII方法仍然需要手动释放资源,而GC机制并不需要开发者手动释放资源(这也是RAII方法和GC机制的一个显著区别),
即RAII并没有剥夺开发者手动管理资源的权限,它只是通过构造和析构函数提供了一种安全管理资源的方法,开发者对于执行过程是具有控制权的.而GC机制把资源的回收过程交由JVM负责,开发者无权控制.
关于可控性,还体现在析构函数和垃圾回收发生的时机上,在C++中通过{}来界定作用范围,当超出作用范围后即会调用对象的析构函数,即析构函数的调用时间是可预知的(适用于对时序有严格要求的场景),而垃圾回收机制的发生时间取决于JVM的资源管理策略,是开发者无权控制的.
前言
资源管理和类的控制实际是两个分离的过程,RAII方法则是利用类的成员函数解决资源管理的方法之一
普通构造函数
无参
-
自定义
1.1 普通形式
1.2 使用初始化表达式 -
默认
POD陷阱(哪些类型不会自动初始化为0,大括号指定初始化值(0初始化方式))或等号指定初始化值(无法采用小括号指定初始化值)
支持单纯的大括号初始化,等号和大括号同时使用的初始化方式
当自定义构造函数后,默认无参构造函数就不存在了,可通过default生成默认的无参构造函数
单参数
此时单参数的构造函数,实现了从一种类型隐式地转换为类类型,因此此时的构造函数也称为转换构造函数,需要注意的是C++ 类型转换中提到的编译器只支持一步隐式类型转换规则.
如果想禁止这种隐式类型转换,可以使用explicit关键字修饰单参数的构造函数,此时该构造函数只能通过直接初始化使用,编译器也不会在隐式类型转换过程中调用该构造函数
额外需要注意的是
explicit关键字只能出现在类内部构造函数声明处
多参数
- 普通形式
- 使用初始化表达式
explicit禁止隐式转换(我自己说的,具体作用要查一下)
拷贝构造函数(copy constructor)
- 定义了用同类型的另一个对象初始化本对象时的操作
拷贝构造函数特征
- 第一个参数是自身类型引用
- 额外参数均存在默认值
- 存在几种情况需要被隐式使用,因此通常不设置为
explicit- 可通过delete禁用拷贝构造函数
拷贝构造函数示例代码
class Foo {
public:
Foo();
Foo(const Foo&);
};
移动构造函数(move constructor)
- 定义了用同类型的另一个对象初始化本对象时的操作
- C++11 引入
移动操作需要理清左值和右值的概念,了解新的右值引用概念
拷贝赋值运算符(copy-assignment operator)
- 定义了将一个对象赋值同类型的另一个对象时的操作
移动赋值运算符(move-assignment operator)
- 定义了将一个对象赋值同类型的另一个对象时的操作
- C++11 引入
解构(析构)函数(destructor)
定义了对象销毁时的操作