目录
-
类:
关键字:class
- C++中的类与c语言的结构体很相似,不同的是,类引入了访问限定符。类有三种访问限定符:private,pubilc,protect三种访问限定符,在类中如果不加访问限定符,则默认为私有
- 访问限定符遇到下一个访问限定符或者除了类作用域结束
- 类是一个域,声明和定义分离是需要指定域
没有成员对象的类大小为1字节,对象实例化的标志是开辟空间,这里的1字节恰好是为了证明该类对象的存在。
面对对象的三大特性:封装,继承,多态
-
封装
在C++中数据与方法都集中一块,C++是采用访问限定符对成员进行限制
在了解封装时,还需要知道对象模型。对象模型:每一个类的对象储存成员变量,但是成员函数是放在一个公共的区域代码段中存放。用同一个类实例化对象,调用同一个成员函数,函数地址是相同的。
-
内存对齐
内存对齐虽然造成空间浪费,但是提高了编译效率,这是一种以空间换时间的方法
如果内存不对齐,会出现重复读取同一块空间的现象,效率低
指定对齐数:#pragma pack(n)
-
构造函数
特点:
- 函数名与类名相同
- 没有返回值
- 对象实例化时,自动调用
- 可以重载
默认生成的构造函数对于内置类型不做处理,自定义类型需要调用自定义类型自己的构造函数,当自定义类型写了构造函数时,编译器就不会自动生成它的默认构造函数
注:构造函数不是创建对象,仅仅只是对对象进行初始化而已
-
析构函数
特点:
- 函数名与构造函数相同,不过需要在前加入特殊符号“~”
- 无参数无返回值
- 一个类只有一个析构函数,且不能被重载
- 析构函数析构成员的顺序:局部成员(先定义的后析构)—>局部静态成员—>全局对象
- 生命周期结束自动调用
-
拷贝构造函数
拷贝构造函数是一个特殊的成员函数
特点:
- 构造函数重载的形式
- 参数只有一个且该参数必须是类类型对象的引用
- 函数名与类名相同
- 自定义类型的调用会产生拷贝构造
为什么调用拷贝构造参数需要传引用?
因为传值传参会调用该函数拷贝其内容,也就是拷贝构造,而拷贝构造的执行是需要进入函数中的,这里由于不能进入函数里,在参数处一直重复的在调用该函数,于是导致了死递。
拷贝构造的参数可以加上 const进行修饰,以免左右值写反
类型转换会产生临时变量,临时变量具有常性
-
深拷贝与浅拷贝:
深拷贝不仅仅只是拷贝数据,深拷贝重新创建了空间存放拷贝的数据,浅拷贝仅仅只是拷贝 了数据
-
运算符重载
关键字:operator
重新定义运算符
运算符重载函数的参数用this指针充当了第一个参数,所以运算符重载的函数形式上只有一个参数,但实际有俩个
注:
- 不能链接其他符号创建新的操作符,例如@
- 重载运算符必须有一个类类型参数
- ·*,::,sizeof,?:,.这五个运算符不可以重载
赋值运算符重载:
- 参数类型需要用const修饰,并引用传参(提高传参效率)
- 用*this指针返回
- 赋值运算符重载函数名加引用,减少拷贝构造
- 赋值运算符重载只能重载成员函数,不可以重载全局函数,会与编译器生成的默认函数冲突
-
初始化列表
格式:以一个冒号开始,以逗号作为一个分隔符,分隔数据成员列表,每一个成员变量后面跟一个放在括号里的初始值表达式
-
必须在初始化列表初始化的成员
- 引用的成员变量
- const成员变量
- 自定义类型成员(且该类没有默认的构造函数时)
const修饰的成员变量为什么只能在初始化列表初始化?
赋值与初始化的区别,两个概念不可以混淆
自定义类型的初始化也需要走初始化列表,没有走初始化列表,就会调用默认构造,但如果自定义函数写了构造函数,而不是编译器默认生成的,在初始化时,没有在初始化列表初始化时,就会发生编译器不知道调用哪个构造函数就会发生报错
自定义类型写在初始化列表的行为叫做显示调用默认构造