文章目录

  • 1.P52 处理多返回值
  • 2.P53 模板
    • 2.1.模板函数
    • 2.2.模板类
      • 2.2.1.将数组大小作为模板参数
      • 2.2.2.将数组大小和数组类型都作为模板参数
    • 2.3.何时使用模板
  • 3.P54 堆和栈内存的比较

1.P52 处理多返回值

参考:视频 笔记

这一节没有什么实质有用的内容,可以大致总结为处理多返回值的两大方式。一个是使用引用或者指针把多个返回值作为形参传入函数;另一个是返回的结果是一个特殊的数据结构,比如结构体、数组、元组等等。

视频中主要讲解了返回结果是一种特殊数据结构的例子,包括结构体、原始数组、array、vector,类型不同的时候可以返回tuple、pair。关于这些内容的具体讲解可以去看上面的参考笔记。

2.P53 模板

参考:视频 笔记

2.1.模板函数

C++模板类似于其他语言的泛型,模板有点像宏然而泛型却非常受制于类型系统。我们可以根据不同的用途来定义编译的模板,模板就是让编译器基于我们给编译器的规则来为我们写代码。当写一个函数里面使用模板,实际上创建了一个蓝本,因此当调用这个函数时,可以指定特定的参数,这个参数决定了放入到模板中的实际代码,也决定了如何使用这个函数。

比如创建一个模板Print函数打印不同类型的数据,注意模板中的类型声明typename也可以写成class,在这里二者是同一个意思,但是为了于类区分习惯上用typename

#include<iostream>
#include<string>template<typename T>  //typename也可以写成class,在这里二者是同一个意思,但是习惯上用typename
void Print(T value)
{std::cout << value << std::endl;
}int main()
{Print(5);//T替换为intPrint("Hello");Print(5.5f);std::cin.get();
}

我们通过单词template定义一个模板,这时的Print函数不是一个真的函数,只有当我们实际调用它时,这些函数才会被真的创建,并作为源代码被编译。若我们不写任何东西,完全没有使用Print函数那么它就没有真正存在过。这个Print函数只是一个模板,只有当调用时才会被实际创建。

我们选择typename作为模板参数的类型,T是模板的参数名称。这里看上去是显示地指定类型,其实这个类型是隐式地从实际参数中得到的,是基于编译器推断出来的。我们还可以调用Print使用尖括号显式地指定传入的模板参数的类型。

Print<int>(5);

2.2.模板类

2.2.1.将数组大小作为模板参数

注意模板不仅可以设置数据类型(比如intfloat),还可以设置其他参数,比如数组的大小。因为模板是在编译期间被评估的,也就是模板的参数是在编译期间被转换成实际代码的。所以对于在栈上分配的数组,要求必须在编译时就知道其大小,此时使用模板参数指定这个大小非常合适。这里模板参数的作用和宏定义非常相似。

实例:我们创建一个在栈上的Array类,其成员变量是一个数组,数组大小是在编译时确定的,不能直接输入一个变量size之类。

class Array
{private:int m_Array[size];
};

因为这是一个栈分配的数组,所以在编译时就需要知道它。显然我们可以使用动态分配栈内存(alloca)或者其他方法,但我们只想在栈上创建一个普通的C语言风格的数组。

因为size值要在编译时就要知道,而模板会在编译期被评估处理。所以正好可以将数组大小转换成一个模板参数,并且这里我们明确知道存储的数组是int类型,因此不用typename作为模板参数来制定数据类型。

代码如下,声明一个模板参数N,其类型是int,然后在类中数组大小就用这个模板参数N来指定。当我们调用这个Array时,指定一个Array大小为5,命名为array,这意味将第9和11行的N改为5。

2.2.2.将数组大小和数组类型都作为模板参数

若不是显示地指定数组类型是int,想让这个类型也是可变的。因此希望能够在编译时指定这个数组实际的类型,可以添加另一个模板参数T,在数字面前添加这个参数。

template<typename T,int N>

用T来替换原数组中的int,然后得到一个类型为T的数组,它在编译时会被模板指定,模板参数N同样也会在编译时会被模板指定。当实际调用这个Array时,需要指定int作为数组类型,5作为数组大小,也可以把它们变成任何我们想要的东西。


总结:实际上,我们在这里创建的Array与标准数组类std::array在C++标准模板库中的工作方式非常相似,标准模板库有两个模板参数:typesize

2.3.何时使用模板

模板是很有用的一个方法,比如在日志系统中,要记录不同类型的数据,那么使用模板是非常合适的。

但是模板的使用应该适度,不能太过分。假设使用了很多模板,多到需要自己挨个模板函数去看哪个被编译哪个没有被编译,把实际的数据类型往模板参数里填空,那么说明此时使用模板就有点过分了。

3.P54 堆和栈内存的比较

参考:视频 笔记

当程序开始的时候内存被分成了一堆不同的内存区域(包括栈和堆),在应用程序启动后,操作系统将整个程序加载到内存并分配一堆物理RAM以便程序可以运行。堆和栈是RAM中实际存在的两个区域,注意他们都是存储在相同的物理设备上的,都是在RAM内存上。栈通常是一个预定义大小(2M字节左右)的内存区域,堆也是一个预定义默认值的区域,但是它可以随着应用程序的进行而改变。

  1. 堆和栈的不同,主要在于内存分配方式的不同:
  • 栈分配内存:在栈中分配变量时,是栈顶部的指针移动字节,大多数的栈都是倒着来的,即第一个变量存储在更高的内存地址上。栈是把东西堆在一起所以栈分配速度很快。而在栈中分配内存的这个作用域(函数作用域或者空作用域或者循环等都可以)一旦结束,在栈中分配的所有内存都会被弹出,会被释放。释放内存没有任何开销,栈释放内存与分配内存一样不需要将栈指针反向移动然后返回栈指针地址,只要弹出栈中的东西,栈指针自然就回到了作用域开始之前。一条CPU的删除指令就可以释放所有东西。

  • 堆分配内存new关键字实际上调用了一个叫做malloc(memory allocate的缩写)的函数,这样做通常会调用底层操作系统或平台的特定函数,将在堆上为我们分配内存。当启动程序时会得到一定数量的RAM,程序会维护一个叫做空闲列表的东西,它跟踪哪些内存块是空闲的还有在什么位置。在堆上分配内存更容易出现cache misses(缓存不命中)。

  1. 堆栈分配对比:

在栈上分配就是一条CPU命令:

在堆上的分配调用了操作符new,new操作符又调用了malloc,然后要去到空闲列表去检查是否有足够的内存,然后记录分配了多少内存,使用完后还要delete它。

所以我们应尽量在栈上分配,在堆上分配的唯一原因是不能在栈上分配。比如需要这个生命周期比函数的作用域更长,或者需要特别大的数据。

Cherno C++系列笔记17——P52~P54 处理多返回值、模板、堆和栈内存的比较相关推荐

  1. 吉哥系列故事——恨7不成妻(多返回值的数位DP)

    第一次碰到这种题,才发现对数位DP真是不了解 不清楚状态就胡乱转移,还一直以为对了- 定 义 d p [ l e n ] [ m o ] [ w e i m o ] 为 长 l e n , 且 数 字 ...

  2. 堆和栈内存的比较 in C++【C++学习笔记】

    54堆和栈内存的比较 in C++ 当我们的程序开始的时候,程序被分成了一堆不同的内存区域,除了堆和栈以外,还有很多东西,但我们最关心这两个

  3. 【Mac 教程系列第 17 篇】如何找回 Mac 上访达侧边栏上的下载、文稿、隔空投送等文件夹选项

    这是[Mac 教程系列第 17 篇],如果觉得有用的话,欢迎关注专栏. 一:问题描述 好久没写过关于 Mac 的博客了,也是因为平常没遇到过什么问题. 前几天准备 git clone 一个项目到[下载 ...

  4. 华为HCIA-datacom 学习笔记17——IPv6基础

    华为HCIA-datacom 学习笔记17--IPv6基础 IPv6基础 1.ipv4与ipv6 地址长度32bit IPv6:IP地址长度128bit IPv4包头(20byte~60byte) I ...

  5. 机器学习系列笔记六:主成分分析PCA[下]

    机器学习系列笔记六:主成分分析PCA[下] 文章目录 机器学习系列笔记六:主成分分析PCA[下] scikit-learn中的PCA 基本使用 进阶操作 对比实验 设置合理的n_components ...

  6. Java全栈系列笔记

    Java全栈系列笔记 全部文档.项目.源码: github:https://github.com/name365/Blog-Java 码云:https://gitee.com/yang365/Blog ...

  7. [网络安全学习篇17]:三层交换机、HSRP、网络规划(千峰网络安全视频笔记 17 day)

    引言:我的系列博客[网络安全学习篇]上线了,小编也是初次创作博客,经验不足:对千峰网络信息安全开源的视频公开课程的学习整理的笔记整理的也比较粗糙,其实看到目录有300多集的时候,讲道理,有点怂了,所以 ...

  8. 数据库,计算机网络、操作系统刷题笔记17

    数据库,计算机网络.操作系统刷题笔记17 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 测开的话,你就得学数据库,sql,oracle,尤其s ...

  9. Cocos2dx游戏开发系列笔记6:怎样让《萝莉快跑》的例子运行在vs和手机上

    2019独角兽企业重金招聘Python工程师标准>>> 感谢听D同学赞助的Demo. 那怎样让它运行在vs中呢: 1 使用cocos2d-x-2.2\tools\project-cr ...

最新文章

  1. android播放页蒙层过渡效果,EasyGuideLayer: 这可能是最简单、灵活、强大的页面蒙层组件了!...
  2. lambda expressions are not supported at this language level
  3. Centos与Ubuntu
  4. 【转】PCA算法学习_1(OpenCV中PCA实现人脸降维)
  5. 2017年我国智能卡行业市场现状及发展趋势分析
  6. strcmp java_C语言中strcmp的实现原型
  7. Verizon的SDN策略:不鸣则已,一鸣惊人?
  8. 软考信息安全工程师备考笔记3:第三章网络安全基础备考要点
  9. [SDOI2006]二进制方程 并查集
  10. (转)使用Spring注解方式管理事务与传播行为详解
  11. php采集扩展,PHP扩展生成器
  12. H5 播放视频常见bug及解决方案
  13. Spring boot yml文件的书写格式
  14. pyecharts制作交互式数据展示地图
  15. 2022年,想自学java有没有一个详细的框架?
  16. Iometer存储测试工具参数说明-3 results display
  17. Python 一个漂亮的音乐节奏可视化方案
  18. 小程序(倒计时的制作)
  19. 5G NR — 载波聚合
  20. 17正交矩阵和Gram-Schmidt正交化

热门文章

  1. DevOps2.0的工具集系列之DevOps理念
  2. hackthebox-buff(gym渗透 端口转发 cloudme 缓冲区溢出 )
  3. L1-020 帅到没朋友 (20分)
  4. ubuntu 串口调试工具推荐_升级版全系列视频第一个项目电子产品量产测试与烧录工具...
  5. AI—漂亮的花简单制作(含详细教程)
  6. android 最新头条适配,今日头条屏幕适配方案终极版正式发布!
  7. 做到 3 点能让你的晶格玻璃更好用
  8. maya多边形建模怎样做曲面_Maya多边形建模教程(三)
  9. java 废弃注解_Java 注解
  10. 【多视角立体视觉系列】 几何变换的层次——投影变换,仿射变换,度量变换和欧几里德变换