1、内区分区模型
1.1 全局区
全局变量和静态变量离得很近
1.2 栈区
由编译器自动分配释放,存放函数的参数值,局部变量等 注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放
1.3 堆区
由程序员分配释放,若程序员不释放,程序结束时由操作系统回收,在C++中主要利用new在堆区开辟内存
1.4 new运算符
C++中利用new操作符在堆区开辟数据; 堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符delete; 语法:new 数据类型; 利用new创建的数据,会返回该数据对应的类型的指针
2 引用
2.1 引用的基本使用
作用:给变量起别名 语法:数据类型 &别名=原名
2.2 引用注意事项
2.3 引用做函数参数
作用:函数传参时,可以利用引用的技术让形参修饰实参 优点:可以简化指针修改实参
通过引用参数产生的效果同按地址传递是一样的,引用的语法更清楚简单
2.4 引用做函数返回值
作用:引用是可以作为函数的返回值存在的 注意:不要返回局部变量引用 用法:函数调用作为左值
2.5 引用的本质
引用的本质是一个指针常量,一旦初始化后,指向不可改变
C++推荐使用引用技术,因为语法方便,引用本质是指针常量,但是所有的指针操作编译器都帮我们做了
2.6 常量引用
作用:常量引用主要用来修饰形参,防止误操作; 在函数形参列表中,可以加const修饰形参,防止形参改变实参
3、函数提高
3.1 函数默认参数
在C++中,函数的形参列表中的形参是可以有默认值的 语法:返回值类型 函数名(参数=默认值){ }
3.2 函数的占位参数
C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置
3.3 函数重载
作用:函数名可以相同,提高复用性
函数重载满足条件:
- 同一个作用域下
- 函数名称相同
- 函数参数类型不同,或者个数不同或者顺序不同
函数重载注意事项: 1.引用作为重载条件 2.函数重载碰到函数默认参数
4、类和对象
C++面向对象三大特性:封装、继承和多态
4.1 封装
封装的意义
- 将属性和行为作为一个整体,表现生活中的事物
- 将属性和行为加以权限控制
语法:
class 类名{访问权限:属性 /行为}
类在设计时,可以把属性和行为放在不同的权限下,加以控制访问权限有三种:
- public 公共权限
- protected 保护权限
- private 私有权限
4.1.1 struct和class区别
在C++中struct和class唯一的区别就在于默认的访问权限不同:
- struct默认权限为公共
- class默认权限 为私有
4.1.2 成员属性设置为私有
- 优点1:将所有成员属性设置为私有,可以自己控制读写权限
- 优点2:对于写权限,我们可以检测数据的有效性
4.2 对象的初始化和清理
构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用 析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作
如果我们不提供构造和析构,编译器会提供,编译器提供的构造函数和析构函数是空实现
4.3 构造函数的分类及调用
两种分类方式:
按参数分为:有参构造和无参构造 按类型分为:普通构造和拷贝构造
三种调用方式:
- 括号法
- 显示法
- 隐式转换法
括号法: 显示法: 匿名对象
隐式转换法
4.3.1 拷贝构造函数调用时机
C++中拷贝构造函数调用时机通常有三种情况:
- 使用一个已经创建完毕的对象来初始化一个新对象
- 值传递的方式给函数参数传值
- 以值方式返回局部对象
1.使用一个已经创建完毕的对象来初始化一个新对象
2.值传递的方式给函数参数传值 3.值的方式返回局部对象
4.3.2 构造函数调用规则
默认情况下,C++编译器至少给一个类添加3个函数
- 默认构造函数(无参,函数体为空)
- 默认析构函数(无参,函数体为空)
- 默认拷贝构造函数,对属性进行值拷贝
构造函数调用规则如下:
- 如果用户定义有参构造函数,C++不再提供默认无参构造,但是会提供默认拷贝构造
- 如果用户定义拷贝构造函数,C++不会再提供其他构造函数
4.3.3 深拷贝与浅拷贝
浅拷贝:简单的赋值拷贝操作 深拷贝:在堆区重新申请空间,进行拷贝操作
浅拷贝带来的问题就是堆区的内存重复释放
深拷贝就是自己实现拷贝构造函数,在堆区重新创建内存空间 ,解决浅拷贝带来的问题,析构函数可以释放堆区内存; 如果不利于深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区问题
总结:如果属性有在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题
4.3.4 初始化列表
作用:C++提供了初始化列表语法,用来初始化属性 语法:构造函数():属性1(值1),属性2(值2)……{}
4.3.5 类对象作为类成员
C++类中的成员可以是另一个类的对象,称该成员为对象成员
构造顺序是:先调用对象成员的构造,再调用本类构造; 析构顺序与构造相反
4.3.6 静态成员
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员 静态成员变量:
- 所有对象共享同一份数据
- 在编译阶段分配内存
- 类内声明,类外初始化
静态成员函数:
- 所有对象共享同一个函数
- 静态成员函数只能访问静态成员变量
4.4 C++对象模型和this指针
4.4.1 C++对象模型
在C++中,类内的成员变量和成员函数分开存储; 只有非静态成员变量才属于类的对象上
空对象占用内存为1
4.4.2 this指针
每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码 问题:这一块代码是如何区分哪个对象调用自己呢
C++通过提供特殊的对象指针,this指针,解决上述问题 this指针指向被调用的成员函数所属的对象 this指针是隐含每一个非静态成员函数内的一种指针 this指针不需要定义,直接使用即可
this指针的用途:
-
当形参和成员变量同名时,可用this指针来区分 ;this可以直接用,不需要定义 -
在类的非静态成员函数中返回对象本身,可使用return *this(可实现链式编程) 如果以值的形式返回 ,会创建新对象,但是以引用形式不会创建新对象
4.4.3 空指针访问成员函数
空指针可以调用成员函数,但是要注意有没有用到this指针 如果用到this指针,需要加以判断保证代码的健壮性
4.3.4 const修饰成员函数
常函数:
- 成员函数加const后称为常函数
- 常函数不可以修改成员属性
- 成员属性声明时加关键字mutable后,在常函数中依旧可以修改
常对象:
- 声明对象前加const称该对象为常对象
- 常对象只能调用常函数
|