IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++标准语言day02 -> 正文阅读

[C++知识库]C++标准语言day02

一、函数重载

? ? 1、什么是函数重载

? ? ? ? 在同一作用域下,函数名相同、参数列表(参数个数或类型)不同的函数构成重载关系

? ? ? ? 函数重载与返回值类型、参数名无关

? ? 2、C++是如何实现函数重载的

? ? ? ? 通过g++ -S xxx.cpp 生成汇编代码得知,编译器会把函数的参数类型缩写后追加到函数名后面,

? ? ? ? ? ? 也就是说编译时会给函数进行换名

? ? 3、extern "C"

? ? ? ? 因为C++编译器在编译函数调用语句时,会找换名后的函数调用,这样就无法调用到已经使用C编译成功的函数了

? ? ? ? 使用 extern "C" 会让C++编译器按照C编译器的格式来翻译函数名,这样函数的声明与定义就匹配,

? ? ? ? ? ? 就可以正确地调用C标准库、系统库函数

? ? 4、重载和隐藏

? ? ? ? 在同一作用域下,函数名相同、参数不同的函数构成重载关系

? ? ? ? 在不同作用域(父子类)下的同名函数遵循名字隐藏原则

? ? 5、参数的类型转换

? ? ? ? 当调用函数时,编译器会优先调用类型最精确的函数,如果没有则会做一定程度的类型提升,而不是全部直接报错 ?

? ? ? ? 但具体优先级与编译器有关,因此最优选择最准确的参数即可,否则容易产生函数调用的二义性 ?

二、默认形参

? ? 1、什么是默认形参

? ? ? ? C++中可以给函数的参数设置默认值,当函数调用者提供了实参则使用实参,如果没有提供则使用默认值

? ? 2、默认形参要靠右

? ? ? ? 如果函数有多个参数,设置了默认形参,必须遵循从右往左依次设置,否则有二义性

? ? 3、只能在函数声明处设置默认形参

? ? ? ? 如果函数声明与定义分开实现,只能在函数声明时设置默认形参,否则语法错误

? ? 4、默认形参可能会影响函数重载的效果

? ? ? ? 如果对同名函数进行了重载,又设置了默认形参,则调用时可能会有冲突

? ? ? ? 因此为重载过的函数设置默认形参时一定要小心

三、内联函数

? ? 1、普通函数

? ? ? ? 普通函数会被翻译成二进制指令存储在代码段中,调用语句会生成一句跳转指令,并让程序跳转到该函数所在代码段处运行

? ? ? ? ? ? 运行结束再返回

? ? 2、内联函数

? ? ? ? 内联函数也会被翻译成二进制指令,调用语句不会生成跳转指令,而是直接把函数的二进制指令替换调用语句

? ? ? ? ? ? 这样既没有跳转也没有返回,而是直接往下执行被调函数,这种函数称为内联函数

? ? 3、显示内联和隐式内联

? ? ? ? 显示内联:在函数的返回值前面加 inline, 则该函数就以内联机制调用

? ? ? ? ? ? 但并不是所有编译器都支持内联机制,我们现在的g++ gcc都不支持

? ? ? ? 隐式内联: 结构、联合、类中的成员函数会自动被当作内联函数处理

? ? 4、内联函数的适用条件

? ? ? ? 内联的优点:

? ? ? ? ? ? 节约了函数跳转、返回、传参的时间,提高了代码的运行速度

? ? ? ? 内联的缺点:

? ? ? ? ? ? 当多处调用内联函数时,它的二进制指令会被拷贝多份,产生代码冗余,导致最终的可执行文件增大

? ? ? ? 适用的条件:

? ? ? ? ? ? 1、适合内容简单且一次调用多次执行的情况,因此不适合内容多且调用又少的函数

? ? ? ? ? ? ? ? 因为这样节约的时间还弥补不了牺牲的内存

? ? ? ? ? ? 2、带有递归属性的函数无法内联,编译器会自动屏蔽inline关键

? ? 5、内联函数(inline)与宏函数(#define)的相同点和不同点?

? ? 相同点:

? ? ? ? 提高了代码的运行速度,使代码变得通用。

? ? 不同点:

? ? ? ? 1、内联函数是在编译时展开,而宏在预编译时展开;

? ? ? ? ? ? 在编译的时候,内联函数直接把函数的二进制指令替换调用语句,而宏只是一个简单的文本替换。

? ? ? ? 2、内联函数可以进行诸如类型安全检查、语句是否正确等编译功能,宏不具有这样的功能;宏不是函数,而inline是函数。

? ? ? ? 3、宏在定义时要小心处理宏参数,一般用括号括起来,否则容易出现二义性。而内联函数不会出现二义性。

? ? ? ? 4、inline有点类似于宏定义,但是它和宏定义不同的是,宏定义只是简单的文本替换,是在预编译阶段进行的。

? ? ? ? ? ? 而inline的引入正是为了取消这种复杂的宏定义的。

四、引用

? ? 什么是引用:引用是一种取别名的机制,

? ? 为什么要使用指针:

? ? ? ? 1、跨函数共享变量(输出型参数)时,引用可替代

? ? ? ? 2、提高传参效率,引用可替代,且效率更高,引用不占字节

? ? ? ? 3、配合字符串时,string可以替代

? ? ? ? 4、配合堆内存使用,继续使用指针

? ? 什么情况下适合引用:

? ? ? ? 1、跨函数共享变量时,引用比指针安全(不存在空引用、极少出现野引用)、引用比指针更方便(不用取地址、不用解引用)

? ? ? ? 2、提高传参效率,引用的传参效率比指针还高,因为指针还需要4\8字节用于存储内存地址,而引用一个字节都不需要

? ? ? ? ? ? 但是引用与指针一样有着被修改的风险,因此为了安全需要加const保护一下

? ? 重点:指针与引用的相同点和不同点:

? ? ? ? 相同点:

? ? ? ? ? ? 都可以跨函数共享变量、都可以提高函数传参效率、也都需要const保护

? ? ? ? 不同点:

? ? ? ? ? ? 1、引用是一种取别名的机制,指针是一种数据类型

? ? ? ? ? ? 2、引用不需要额外的存储空间,而指针需要4\8字节内存用于存储内存地址编号

? ? ? ? ? ? 3、引用不能更换指向目标,而指针可以更改指向

? ? ? ? ? ? 4、引用必须初始化,而指针可以不初始化

? ? ? ? ? ? 5、有空指针,但是有空引用

? ? ? ? ? ? 6、指针可以配合堆内存使用,引用不可以

? ? ? ? ? ? 7、可以定义指针数组,但不能定义引用数组(可以定义数组指针,也可以定义数组引用,可以定义函数指针,也可以定义函数引用)

? ?

? ? 使用引用时需要主要的问题:

? ? ? ? 1、引用必须初始化、不存在空的引用

? ? ? ? 2、可以引用右值,但必须使用const修饰

? ? ? ? 3、引用不可以修改目标

? ? ? ? 4、函数返回引用类型的数据时,不要返回局部变量的引用 ? ? ? ?

五、强制类型转换

? ? C语言中强制类型转换还能在C++中继续使用,因此C++中新的强制类型转换有点鸡肋

? ? 为什么C++要重新设计新的强制类型转换机制?

? ? ? ? 因为C语言中的强制类型转换太危险了,没有任何限制

? ? 为什么C++的强制类型转换设计的很复杂、使用麻烦?

? ? ? ? 因为C++之父认为只有在程序设计不合理的时候,才需要进行强制类型转换,

? ? ? ? ? ? 之所以设计复杂就是不想让程序员使用,从而反思、重新设计自己的代码

? ? 1、静态类型转换 ? ? ? ?

? ? ? ? static_cast<目标类型>(原数据)

? ? ? ? 目标类型与原数据类型之间必须有一个方向可以自动类型转换

? ? 2、动态类型转换 ? ?

? ? ? ? dynamic_cast<目标类型>(原数据)

? ? ? ? 目标类型与原数据类型之间必须存在继承关系,否则会出现错误

? ? 3、去常类型转换

? ? ? ? const_cast<目标类型>(原数据)

? ? ? ? 目标类型与原数据类型必须是指针或引用,并且除了是否带const属性区别之外,其他类型都必须相同,否则出错 ? ?

? ? 4、重解释类型转换

? ? ? ? reinterpret_cast<目标类型>(原数据)

? ? ? ? 只能是把整数数据转换成指针,或者把指针转换成整数,否则出错

六、面向对象与面向过程

? ? 面向过程:

? ? ? ? 关注的是如何解决问题、以及解决问题的步骤

? ? 面向对象:

? ? ? ? 抽象:先找出(想象出)能解决问题的"对象",分析该对象解决问题所需要的属性(成员变量)和行为(成员函数)

? ? ? ? 封装:把抽象的结果封装成一个类(结构),并给的类的成员变量、成员函数设置相应的访问权限

? ? ? ? ? ? ? ? (public、protected\private)

? ? ? ? 继承:

? ? ? ? ? ? 1、在封装类之前先考虑现有的类是否能解决一部分问题,如果有则把现有的类继承过来,在此基础上进行扩展

? ? ? ? ? ? ? ? 以此来节约解决问题的时间

? ? ? ? ? ? 2、把一个复杂的问题分析拆解成若干个小问题,每个问题设计一个类去解决,

? ? ? ? ? ? ? ? 最后把这些类通过继承合并到一个能够解决最终问题的类

? ? ? ? 多态:发出一个指令、系统会根据实际情况执行不同相应的操作,这种特征称之为多态(统一命令多种形态)

? ? ? ? ? ? ? ? 例如重载过的函数,当调用函数时,编译器会根据参数的类型调用对应的重载版本,这就是一种多态

? ? ? ? ? ? ? ? 而且具体调用哪个版本如果在编译时就能确定下来,这种重载称为编译时多态

? ? 特别注意:面向对象的行为细节依然是面向过程,因此面向对象只是从更高的维度去思考解决问题,而不是寻求解决问题的捷径

七、类和对象

? ? 什么是类和对象?

? ? ? ? 类是由程序员自己设计的一种数据类型,它里面包含了成员变量和成员函数两部分

? ? ? ? 而对象是类的实例化,其实可以理解为使用类创建的变量

? ? 类的设计和实例化:

? ? ? ? class 类型

? ? ? ? {

? ? ? ? ? ? 成员变量; ?// ?类中成员默认属性是 private 私有

? ? ? ? public:

? ? ? ? ? ? 成员函数;

? ? ? ? };

? ? ? ? 实例化:

? ? ? ? ? ? 方法1: 类名 类对象名;

? ? ? ? ? ? 方法2: 类名* p = new 类型;

? ? ? ?

? ? 类的声明、定义和实例化

? ? ? ? 1、在头文件中声明类

? ? ? ? ? ? class 类型

? ? ? ? ? ? {

? ? ? ? ? ? ? ? 成员变量;

? ? ? ? ? ? public:

? ? ? ? ? ? ? ? 返回值 函数名(参数列表);

? ? ? ? ? ? }; ?// ?分号也不能少

? ? ? ? 2、在源文件中定义类

? ? ? ? ? ? 返回值 类名::函数名(参数列表)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? // ?成员函数内可以直接使用成员变量 不用. ->

? ? ? ? ? ? }

? ? ? ? ? ? 注意:如果类的内容不多,可以考虑在头文件中全部实现出来

? ? ? ? 3、实例化

? ? ? ? ? ? 方法1: 类名 类对象名;

? ? ? ? ? ? 方法2: 类名* p = new 类型;

八、访问控制限定符

? ? private

? ? ? ? 私有的,被它修饰的成员只能在类内访问,是类的默认访问属性

? ? public

? ? ? ? 公开的,被修饰的成员可以在任何位置访问,一般把类的成员设置为公开的

? ? protected

? ? ? ? 保护的,被它修饰的成员可以在类内和子类中访问,但是不能在类外访问

九、构造函数

? ? 构造函数是类的同名函数,没有返回值,当实例化对象时它会自动执行,一般负责对类进行初始化、分配资源

? ? class 类名

? ? {

? ? ? ? int* p;

? ? public:

? ? ? ? 类名(参数)

? ? ? ? {

? ? ? ? ? ? p = new int;

? ? ? ? }

? ? };

? ? 1、构造函数必须是public 否则无法实例化对象

? ? 2、构造函数可以重载,可以有多个版本

? ? 3、带参数的构造函数的调用方法:

? ? ? ? 类名 对象名(实参);

? ? ? ? 类名* 对象指针 = new 类名(实参);

? ? 4、默认情况下编译器会自动生成一个无参构造函数,该函数什么都不做,一旦显示地实现了构造函数,则编译器不生成该函数

? ? ? ? 类名 对象名; ? ?// ?调用无参构造,如果没有无参构造,则报错

? ? 5、也可以通过设置构造函数地默认形参达到无参构造地效果

? ? 6、构造函数没有返回值

? ? 7、不要使用malloc为类实例化对象分配内存,因为malloc不会调用构造函数

十、析构函数

? ? 析构函数负责对类对象进行收尾工作,例如:释放类中的资源、保存数据等,当类对象销毁时会自动调用执行

? ? class 类名

? ? {

? ? ? ? int* p;

? ? public:

? ? ? ? 类名(参数) ?// ?构造

? ? ? ? {

? ? ? ? ? ? p = new int;

? ? ? ? }

? ? ? ? ~类名()

? ? ? ? {

? ? ? ? ? ? delete p;

? ? ? ? }

? ? };

? ? 1、析构函数也必须是public

? ? 2、没有返回值、参数、不能重载

? ? 3、当类对象生命周期完结、或者使用delete销毁对象时会自动调用析构函数

? ? 4、如果没有显示地实现析构函数,编译器也会自动生成一个什么都不干的析构函数

? ? 5、构造函数肯定会执行,但是析构函数不一定执行

? ? 6、不要使用free来销毁对象,因为不会执行析构函数

十一、初始化列表

? ? 初始化列表是构造函数的一种特殊语法,只能在构造函数中使用

? ? class 类名

? ? {

? ? public:

? ? ? ? 类名(参数):成员名1(初始化数据),成员名2(初始化数据)...

? ? ? ? {

? ? ? ? ? ? // ?构造函数

? ? ? ? }

? ? }

? ? 1、类的成员变量在老编译标准中不可以设置初始值,而且在构造函数执行之前成员变量已经定义完毕,

? ? ? ? 因此const属性的成员变量无法在构造函数内正常赋值初始化(新标准中可以直接设置初始值,但是也只能给常量,功能有限)

? ? 2、初始化列表先于构造函数执行的,初始化列表执行时类对象还没有构造完成,

? ? ? ? 因此他是唯一(老标准)一种能给const属性成员变量赋值的方法

? ? 3、当参数名与成员名相同,初始化列表可以自动分辨成员名和参数名

? ? 4、当类中有类类型成员时,该成员的有参构造函数也可以在初始化列表中被执行


?

作业:

? ? 1、使用C++语法实现通讯录

? ? 2、使用C++语法写个五子棋

? ? 3、使用C++语法实现封装NetWork

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-24 20:38:18  更:2022-09-24 20:41:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 13:42:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码