C++ Primer Plus第五版笔记(p201-250)

2024-06-16 01:44

本文主要是介绍C++ Primer Plus第五版笔记(p201-250),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第六章 函数(下)

  1. 在含有return语句的循环后面应该也有一条return语句

  2. 不要返回局部对象的引用或指针,当函数结束时临时对象占用的空间也就随之释放掉了,所以两条return语句都指向了不再可用的内存空间。

  3. 如果函数返回指针、引用或类的对象,我们就能使用函数调用的结果访问结果对象的成员。

  4. 我们能为返回类型是非常量引用的函数的结果赋值

  5. C++11新标准规定,函数可以返回花括号包围的值的列表

  6. 如果函数返回的是内置类型,则花括号包围的列表最多包含一个值
    在这里插入图片描述

  7. 如果控制到达了main 函数的结尾处而且没有return语句,编译器将隐式地插入一条返回0的return语句

  8. 因为数组不能被拷贝,所以函数不能返回数组。

  9. 我们把函数的返回类型放在了形参列表之后,所以可以清楚地看到func函数返回的是一个指针,并目该指针指向了含有10个数的数组。

     auto func(int i) -> int(*)[10]
    
  10. 不允许两个函数除了返回类型外其他所有的要素都相同。

  11. 一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开来;另一方面,如果形参是某种类型的指针或引用,则通过区分其指向的是常量对象还是非常量对象可以实现函数重载,此时的const是底层的
    在这里插入图片描述

  12. 重载对作用域的一般性质并没有什么改变:如果我们在内层作用域中声明名字,它将隐藏外层作用域中声明的同名实体。在不同的作用域中无法重载函数名

  13. 一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。

  14. 尽量让不怎么使用默认值的形参出现在前面,而让那些经常使用默认值的形参出现在后面。

  15. 局部变量不能作为默认实参。除此之外,只要表达式的类型能转换成形参所需的类型,该表达式就能作为默认实参

  16. 一般来说,内联机制用于优化规模较小、流程直接、频繁调用的函数

  17. constexpr函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句

  18. 和其他函数不一样,内联函数和constexpr函数可以在程序中多次定义(头文件)

  19. 当应用程序编写完成准备发布时,要先屏蔽掉调试代码。这种方法用到两项预处理功能:assert和NDEBUG。

  20. assert是一种预处理宏(preprocessor marco) 首先对 expr 求值,如果表达式为假(即0),assert输出信息并终止程序的执行。如果表达式为真(即非0),assert什么也不做。

  21. assert 宏定义在cassert头文件中。如我们所知,预处理名字由预处理器而非编译器管理

  22. assert的行为依赖于一个名为NDEBUG的预处理变量的状态。如果定义了NDEBUG,则assert什么也不做。默认状态下没有定义NDEBUG,此时 assert 将执行运行时检查。

  23. 我们使用变量输出当前调试的函数的名字。编译器为每个函func数都定义了__func__,它是const char 的一个静态数组,用于存放函数的名字
    在这里插入图片描述

在这里插入图片描述

  1. 我们无法把 const 对象、字面值常量或者需要进行类型转换的对象传递给普通的引用形参

  2. 当我们想把数组作为函数的形参时,有三种可供选择的方式:一是声明为指针,二是声明为不限维度的数组,三是声明为维度确定的数组。实际上,因为数组传入函数时实参自动转换成指向数组首元素的指针,所以这三种方式是等价的

在这里插入图片描述

  1. 引用类型的优势主要是可以直接操作所引用的对象以及避免拷贝较为复杂的类类型对象和容器对象。因为 initializer list 对象的元素永远 是常量值,所以我们不可能通过设定引用类型来更改循环控制变量的内容。只有当initializer list对象的元素类型是类类型或容器类型(比如string)时,才有必要把范围 for 循环的循环控制变量设为引用类型。

  2. 如果引用所引的是函数开始之前就已经存在的对象,则返回该引用是有效的:如果引用所引的是函数的局部变量,则随着函数结束局部变量也失效了,此时返回的引用无效。
    当不希望返回的对象被修改时,返回对常量的引用

  3. 函数指针
    在这里插入图片描述
    在这里插入图片描述

第七章 类 (上)

  1. 类的基本思想是数据抽象(data abstraction)和封装(encapsulation)。数据抽象是种依赖于接口(interface)和实现(implementation)分离的编程(以及设计)技术。类的接口包括用户所能执行的操作:
  2. 类的实现则包括类的数据成员、负责接口实现的函数体以及定义类所需的各种私有函数。
  3. 成员函数的声明必须在类的内部,它的定义则既可以在类的内部也可以在类的外部。作为接口组成部分的非成员函数,例如add、read和print等,它们的定义和声明都在类的外部。
  4. 成员函数通过一个名为this的额外的隐式参数来访问调用它的那个对象在这里插入图片描述
  5. 因为 this 的目的总是指向“这个”对象,所以 this 是一个常量指针,我们不允许改变this中保存的地址。
  6. C++语言的做法是允许把const 关键字放在成员函数的参数列表之后,此时,紧跟在参数列表后面的const表示this是一个指向常量的指针。像这样使用const的成员函数被称作常量成员函数
  7. 常量对象,以及常量对象的引用或指针都只能调用常量成员函数
  8. 类本身就是一个作用域
  9. 编译器分两步处理类:首先编译成员的声明,然后才轮到成员函数体(如果有的话)。
  10. 我们无须使用隐式的this指针访问函数调用者的某个具体成员,而是需要把调用函数的对象当成一个整体来访问
  11. 一般来说,如果非成员函数是类接口的组成部分,则这些函数的声明应该与类在同一个头文件内。
  12. 第一点,read和print分别接受一个各自10类型的引用作为其参数,这是因为I0类属于不能被拷贝的类型,因此我们只能通过引用来传递它们
  13. 一般来说,执行输出任务的函数应该尽量减少对格式的控制,这样可以确保由用户代码来决定是否换行。
  14. 我们用1hs的副本来初始化sum。默认情况下,拷贝类的对象其实拷贝的是对象的数据成员
  15. 无论何时只要类的对象被创建,就会执行构造函数。
  16. 构造函数的名字和类名相同。和其他函数不一样的是,构造函数没有返回类型;除此之外类似于其他的函数,构造函数也有一个(可能为空的)参数列表和一个(可能为空的)函数体
  17. 当我们创建类的一个const对象时,直到构造函数完成初始化过程,对象才能真正取得其“常量”属性。因此,构造函数在const对象的构造过程中可以向其写值。
  18. 如果我们的类没有显式地定义构造函数,那么编译器就会为我们隐式地定义一个默认构造函数
  19. 因此,含有内置类型或复合类型成员的类应该在类的内部初始化这些成员,或者定义一个自己的默认构造函数
  20. 我们把新出现的部分称为构造函数初始值列表(constructorinitialize list),它负责为新创建的对象的一个或几个数据成员赋初值。构造函数初始值是成员名字的一个列表,每个名字后面紧跟括号括起来的(或者在花括号内的)成员初始值
  21. 当某个数据成员被构造函数初始值列表忽略时,它将以与合成默认构造函数相同的方式隐式初始化
  22. 构造函数不应该轻易覆盖掉类内的初始值,除非新赋的值与原值不同。如果你不能使用类内初始值,则所有构造函数都应该显式地初始化每个内置类型的成员。
  23. 与其他几个构造函数不同,以istream 为参数的构造函数需要执行一些实际的操作。
  24. 当我们在类的外部定义构造函数时,必须指明该构造函数是哪个类的成员
  25. 管理动态内存的类通常不能依赖于上述操作的合成版本
  26. 不过值得注意的是,很多需要动态内存的类能(而且应该)使用vector对象或者string对象管理必要的存储空间。使用vector或者string的类能避免分配和释放内存带来的复杂性。
  27. struct和class的默认访问权限不太一样:如果我们使用struct关键字,则定义在第一个访问说明符之前的成员是public的:相反,如果我们使用class关键字,则这些成员是private的。出于统一编程风格的考虑,当我们希望定义的类的所有成员是public的时,使用struct;反之,如果希望成员是private的,使用class。
  28. 类可以允许其他类或者函数访问它的非公有成员,方法是令其他类或者函数成为它的友元(friend)
  29. 友元声明只能出现在类定义的内部,但是在类内出现的具体位置不限
  30. 友元的声明仅仅指定了访问的权限,而非一个通常意义上的函数声明。如果我们希望类的用户能够调用某个友元函数,那么我们就必须在友元声明之外再专门对函数进行一次声明。

这篇关于C++ Primer Plus第五版笔记(p201-250)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1065165

相关文章

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

C++的模板(八):子系统

平常所见的大部分模板代码,模板所传的参数类型,到了模板里面,或实例化为对象,或嵌入模板内部结构中,或在模板内又派生了子类。不管怎样,最终他们在模板内,直接或间接,都实例化成对象了。 但这不是唯一的用法。试想一下。如果在模板内限制调用参数类型的构造函数会发生什么?参数类的对象在模板内无法构造。他们只能从模板的成员函数传入。模板不保存这些对象或者只保存他们的指针。因为构造函数被分离,这些指针在模板外

Tolua使用笔记(上)

目录   1.准备工作 2.运行例子 01.HelloWorld:在C#中,创建和销毁Lua虚拟机 和 简单调用。 02.ScriptsFromFile:在C#中,对一个lua文件的执行调用 03.CallLuaFunction:在C#中,对lua函数的操作 04.AccessingLuaVariables:在C#中,对lua变量的操作 05.LuaCoroutine:在Lua中,

AssetBundle学习笔记

AssetBundle是unity自定义的资源格式,通过调用引擎的资源打包接口对资源进行打包成.assetbundle格式的资源包。本文介绍了AssetBundle的生成,使用,加载,卸载以及Unity资源更新的一个基本步骤。 目录 1.定义: 2.AssetBundle的生成: 1)设置AssetBundle包的属性——通过编辑器界面 补充:分组策略 2)调用引擎接口API

C++工程编译链接错误汇总VisualStudio

目录 一些小的知识点 make工具 可以使用windows下的事件查看器崩溃的地方 dumpbin工具查看dll是32位还是64位的 _MSC_VER .cc 和.cpp 【VC++目录中的包含目录】 vs 【C/C++常规中的附加包含目录】——头文件所在目录如何怎么添加,添加了以后搜索头文件就会到这些个路径下搜索了 include<> 和 include"" WinMain 和

C/C++的编译和链接过程

目录 从源文件生成可执行文件(书中第2章) 1.Preprocessing预处理——预处理器cpp 2.Compilation编译——编译器cll ps:vs中优化选项设置 3.Assembly汇编——汇编器as ps:vs中汇编输出文件设置 4.Linking链接——链接器ld 符号 模块,库 链接过程——链接器 链接过程 1.简单链接的例子 2.链接过程 3.地址和

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C++学习 贝蒂的主页:Betty’s blog 1. 泛型编程 首先让我们来思考一个问题,如何实现一个交换函数? void swap(int& x, int& y){int tmp = x;x = y;y = tmp;} 相信大家很快就能写出上面这段代码,但是如果要求这个交换函数支持字符型

《offer来了》第二章学习笔记

1.集合 Java四种集合:List、Queue、Set和Map 1.1.List:可重复 有序的Collection ArrayList: 基于数组实现,增删慢,查询快,线程不安全 Vector: 基于数组实现,增删慢,查询快,线程安全 LinkedList: 基于双向链实现,增删快,查询慢,线程不安全 1.2.Queue:队列 ArrayBlockingQueue:

C++入门01

1、.h和.cpp 源文件 (.cpp)源文件是C++程序的实际实现代码文件,其中包含了具体的函数和类的定义、实现以及其他相关的代码。主要特点如下:实现代码: 源文件中包含了函数、类的具体实现代码,用于实现程序的功能。编译单元: 源文件通常是一个编译单元,即单独编译的基本单位。每个源文件都会经过编译器的处理,生成对应的目标文件。包含头文件: 源文件可以通过#include指令引入头文件,以使