C++中对象的行为
C++中对象的行为就是对象的函数。在C++中对象有以下几类函数:
-
构造函数
- 默认构造
- 有参构造
- 拷贝构造
- 移动构造
-
赋值运算符函数
- 拷贝赋值
- 移动赋值
-
普通函数调用
- 覆盖函数
- 重载函数
-
虚函数调用
- 纯虚函数
- 非纯虚函数
-
析构函数
- 虚析构函数
- 非虚析构函数
由于静态函数是属于类的,而不是对象。所以,静态函数不能算是对象的行为。
-
三/五原则
对象移动
为了支持对象的移动,需要引入一个新的引用类型 – 右值引用。
-
在C++中有两种类型的值:
-
左值:持久、表示一个对象的身份,例如:变量
-
右值:短暂、表示一个对象的值,例如:表达式计算过程中产生的临时对象、字面常量
-
左值引用:
- 对左值的引用
- 不可以绑定到右值
- const的左值引用可以绑定到右值上
- 左值引用之间可以相互赋值
int &r1 = i + 10; // 错误,i是一个变量 是左值,但是 i + 10 这个表达式是右值 const int &r2 = i + 10; // 正确
-
右值引用:
- 对右值的引用
- 不可以绑定到左值上
- 右值引用之间不可以相互赋值
int &&rr1 = 10; // 正确,字面量10是一个右值 int &&rr2 = rr1; // 错误,rr1是个变量 是左值,尽管rr1是右值引用
-
-
标准库move函数
将一个左值转换为对应的右值引用。
int &&rr1 = 10; int &&rr2 = std::move(rr1); // 对左值rr1调用move后,不对rr1中的内容做保证,所以不要再使用rr1的值
构造函数
构造函数的意义在于完成对象的初始化工作。在继承中,构造函数会调用基类的构造函数完成对象中基类部分的初始化。但是,类的构造函数应该只负责完成自己的成员的初始化。
-
默认构造函数
struct Base { Base() { ... } } // 自定义默认构造函数 struct Base { ... } // 隐式使用编译器版本 struct Base { Base() = default; } // 显示使用编译器合成版本 /* 调用 */ Base b; Base b(); Base b = Base(); // 三者都会调用默认构造函数
- 使用new运算符调用构造函数
/* 内置类型 */ int *a = new int; // 未初始化,对象的值不确定 int *a = new