C++入门学习(黑马程序员课程讲义)——第二阶段

本阶段主要针对C++面向对象编程技术

1. 内存分区模型

C++程序在执行时,将内存大方向划分为4个区域:
代码区:存放函数体的二进制代码,由操作系统进行管理的
全局区:存放全局变量和静态变量以及常量
栈区:由编译器自动分配和释放,存放函数的参数值,局部变量等
堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

内存四区的意义:不同区域存放的数据,赋予不同的生命周期,给予更大的灵活编程

1.1 程序运行前

在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域:
代码区:
存放CPU执行的机器指令(二进制)
代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可(避免资源浪费)
代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

全局区:
全局变量和静态变量存放在此
全局区还包含了常量区,字符串常量和const修饰的全局变量(即全局常量)也存放在此(const修饰的局部变量,即局部常量,是和局部变量放在一块)
该区域的数据在程序结束后由操作系统释放

总结:
• C++中在程序运行前分为代码区和全局区
• 代码区的特点是共享和只读
• 全局区中存放全局变量,静态变量,常量
• 常量区中存放了字符串常量和const修饰的全局变量
• 局部变量和const修饰的局部变量不在全局区(在栈区)

1.2 程序运行后

栈区:
由编译器自动分配释放,存放函数的形参、局部变量等
注:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放

堆区:
由程序员分配释放,若程序员不释放,程序结束时由操作系统回收
在C++中主要利用new关键字在堆区开辟内存

总结:
• 堆区数据由管理员开辟和释放
• 堆区(自由存储区)数据利用new关键字进行开辟内存

1.3 new操作符

C++中利用new操作符在堆区开辟数据
堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符delete
语法:new 数据类型
new 数据类型 告诉程序需要适合存储该数据类型的内存,然后它找到这样的内存,并返回其地址

1.4 delete运算符

使用delete时,后面要加上指向new分配的内存块的指针(即用于new的地址)
对空指针使用delete是安全的
注意:一定要配对的使用new和delete,否则将发生内存泄漏。

总结:
使用new和delete应遵守的规则有( C++ Primer Plus P87):
• 不要用delete来释放不是new分配的内存
• 不要使用delete释放同一个内存块两次
• 如果使用new[ ]为数组分配内存,则应使用delete[ ]来释放
• 如果使用new为一个实体分配内存,则应使用delete来释放
• 对空指针使用delete是安全的

2. 引用

2.1 引用的基本使用

作用:给变量起别名
语法:数据类型 & 别名 = 原名 ( 数据类型和原来的变量的类型是一样的)
引用也是地址的别名
引用的本质是一个指针常量,指针指向的值可以修改,但是指针指向的地址不能改变,占四个字节

2.2 引用注意事项

①引用必须初始化
②引用在初始化后,不可以改变(指针常量)

2.3 引用做函数参数(引用传递)

作用:函数传参时,可以利用引用的技术让形参修饰实参(C++Primer Plus P212)
优点:通过引用参数产生的效果同按地址传递是一样的,引用传递可以简化指针修改实参

2.4 引用做函数返回值

作用:引用是可以作为函数的返回值存在的
用法:如果函数的返回值是引用,则这个函数调用可以作为左值
注意:不要返回局部变量引用 (C++Primer Plus P312)

2.5 引用的本质

本质:引用的本质在C++内部实现是一个指针常量

2.6 常量引用

作用:常量引用主要用来修饰形参,防止误操作
在函数形参列表中,可以加const修饰形参,防止形参改变实参

3. 函数提高

3.1 函数默认参数

在C++中,函数的形参列表中的形参列表是可以有默认值的
语法:返回值类型 函数名(形参 = 默认值){ }
注意:
①如果某个位置已经有了默认参数,那么从这个位置后,从左向右都必须有默认值
②如果函数声明有默认参数,函数实现就不能有默认参数(声明和实现只有一个能有默认参数)

3.2 函数占位参数

C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置
语法:返回值类型 函数名 (数据类型){ }

3.3 函数重载

3.3.1函数重载概述
作用:函数名可以相同,提高复用性
函数重载的关键是函数的参数列表,也叫做函数特征标

函数重载的满足条件:
①同一个作用域下
②函数名称相同
③函数参数类型不同或者个数不同或者顺序不同

注意:函数的返回值类型不可以作为函数重载的条件

3.3.2 函数重载的注意事项
①引用作为重载条件
②函数重载碰到函数默认参数(产生歧义,要避免)
③不要滥用函数重载,仅当函数基本上执行相同的任务,但使用不同形式的数据时,才应该采用函数重载

4. 类和对象

C++面向对象的三大特性:封装、继承和多态
C++认为万事万物皆为对象,对象上有其属性和行为
具有相同性质的对象,可以抽象为类,人属于人类,车属于车类
类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操纵数据的方法组合成一个简洁的包。

4.1 封装

4.1.1 封装的意义
封装是C++面向对象三大特性之一
封装的意义:
①将属性和行为作为一个整体,表现生活中的事物
②将属性和行为加以权限控制

封装意义①:
在设计类的时候,属性(变量)和行为(函数)写在一起,表现事物(变量一般放在私有,函数放在公有)
语法:class 类名{ 访问权限: 属性 / 行为 };

封装意义②:
类在设计时,可以把属性和行为放在不同的权限下,加以限制
访问权限有三种:
1.public 公共权限
2.protected 保护权限
3.private 私有权限

4.1.2 struct和class的区别
在C++中struct和class唯一的区别就在于默认的访问权限不同
区别:
①struct默认权限为公共
②class默认权限为私有

4.1.3 成员属性设置为私有
优点1:将所有成员属性设置为私有,可以自己控制读写权限
优点2:对于写权限,我们可以检测数据的有效性

4.2 对象的初始化和清理

C++中的面向对象来源于生活,每个对象也都会有初始化设置以及对象销毁前的清理数据的设置。

4.2.1 构造函数和析构函数
对象的初始化和清理也是两个非常重要的安全问题,一个对象或者变量没有初始状态,对其使用后果是未知;同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题。
C++利用了构造函数(做初始化)和析构函数(清理)解决上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。如果我们不提供构造和析构,编译器会提供,编译器提供的构造函数和析构函数是空实现。

**构造函数:**主要作用在创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用。
语法:类名(){}
1.构造函数,没有返回值也不写void
2.函数名称与类名相同
3.构造函数可以有参数,因此可以发生重载
4.程序在调用对象的时候会自动调用构造,无需手动调用,而且只会调用一次

**析构函数:**主要作用在对象销毁前系统自动调用,执行一些清理工作。
语法:~类名(){}
1.析构函数,没有返回值也不写void
2.函数名称与类名相同,在名称前面加~
3.析构函数不可以有参数,因此不可以发生重载
4.程序在对象销毁前会自动调用析构,无需手动调用,而且只会调用一次

  • 3
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值