C++ primer Plus 第八章:函数探幽

C++ 类与对象_类的其他成员(常成员,静态成员,友元) 系列文章目录 重新复习c++,所以把书中的重点内容整理成博客,尽量简洁,易懂。 文章目录系列文章目录前言一、常成员1.常数据成员2.常对象3.常成员函数二、静态成员1.静态数据成员2.静态成员函数三、友元1.友元函数2.友元类 前言 这里讨论的是约束为只读的常成员,类对象共享的静态成员,具有最高访问权限的友元。 一、常成员 1.常数据成员 const可以约束基本类型的数据成员为常数据成员。 有两种方式对常数据成员进行初始化 1、在构造函数中直接用常量进行初始化,这样每个对象建立的常数据成员都有相同的 阅读详情

目录

1.为什么要使用内联函数?

2.如何使用内联函数

3.内联函数与宏

4.引用变量

6.关于对象的引用

7.使用引用的原因

8.引用、指针、值的使用情况

9.默认参数

10.函数重载

11.函数模板

什么时候使用模板?


1.为什么要使用内联函数?

执行函数调用指令的时候,程序将在函数调用后立即储存该指令的内存地址,并将函数参数复制到堆栈,跳到标记函数起点的内存单元,执行函数代码,然后条回到保存的那条指令的内存地址。这意味着执行函数要来回的跳跃位置,所以执行函数需要一定的开销。

而内联函数,编译器会将它的函数代码替换相关的函数调用。(这一过程在编译的时候实现,并不使用程序运行时候的时间,因此提高了函数的效率)

inline double fun(int a)
{
   return a*a;
}

int main()
{
   int i=2;
   cout<<fun(i)<<endl;
   return 0;
}
//若使用内联函数
cout<<fun(i)<<endl;就会变成cout<<i*i<<endl;

2.如何使用内联函数

在函数前面加上inline。

在类的成员函数可以直接在类的内部给出函数体,不用加inline就可以成为内联函数。

内联函数的限制

  1. 函数内不能有循环或者switch结构
  2. 不能有任何静态数据和数组的声明
  3. 不能是递归函数

这里注意一点,inline函数不区分声明和定义。

并不是所有函数都可以成为内联函数,如果一个函数含有循环 switch等语句编译器将不会将其解释为内联函数,即使你使用了inline。就是说我们只有建议内联的权利,是否真的实现内联还要由编译器决定

3.内联函数与宏

#define square(x) x*x

a= square(5);  会被解释成 5*5 是对的
b= square(1+2); 会被解释成 1+2*1+2 出错了
c= square(b++); 会被解释成 b++*b++

使用宏可能会出错,使用内联函数则不会。

其次,内联函数还有一个优点,它有返回类型,也就是说,编译器可以通过检查返回类型来检查是否出错,而宏定义没有返回类型。

4.引用变量

语法:

int a=1;

int & i=a;

引用只能指向一个变量,一旦指向后就不可更改。

可以通过改变i来改变a,其实引用是用指针实现的,int &i = a可以理解为,int const *i=&a;一个指向int变量的常指针,C++的设计者,简化了这些符号,使用了&。

#include <iostream>
#include<exception>
using namespace std;


int main()
{
    int a = 3;
    int b = 4;
    int & c = a;
    cout << "c="<<c << endl;
    c = b;
    cout << "step1:" << endl;
    cout << "c="<<c << endl;
    cout << "输出c等于4,难道改变了引用的指向,使c指向了b!?" << endl;

    cout << "step2:" << endl;
    b = 5;
    cout << "c="<<c << endl;
    cout << "改变b的值,c并未发生变化,说明c没有指向b" << endl;

    cout << "step3:" << endl;
    cout << "a=" << a << endl;
    cout << "引用就是给变量取别名,c引用a说明c就是a的别名,c=b相当于a=b,其实就是对a进行了赋值操作,所以a的值发生了变化" << endl;

    cout << "step4:" << endl;
    a = 6;
    cout << "c="<<c << endl;
    cout << "改变a的值,c发生变化,说明c任然是指向a" << endl;

    cout << endl<<"结论:不能改变引用的指向"<<endl;

    return 0;
}

5.将引用作为函数参数

函数参数如果不是指针的话,程序会为其创建一个副本,将副本传过去,这就意味着需要花费时间和内存,使用指针可以优化这个过程,直接传一个地址过去,让函数直接访问这个地址里的数据,减少了时间开销。上面提到引用时常指针,因此用引用也可以起到减少时间开销的作用。

函数参数为引用的话,不能传一个表达式过去 例如 fun(x +3)

如果实参与引用参数不匹配但可以转换成正确的类型或者实参类型正确,但不是左值,C++会生成临时变量。

仅当参数为const引用时,C++才允许这样做。

#include<iostream>
using namespace std;
void print(const int &a)
{
  cout<<a<<endl;
}

int main()
{
  long a,b;
  a=1,b=2;
  print(a+3);
  return 0;
}

个人认为,const是用来规范的,意思就是你类型不对,程序会创建一个正确类型的副本,并使形参引用他,那么即使你修改了形参,也不会改变主函数里的数据。所以一般这种情况,加一个const,相当于告诉编译器让它来帮忙检查程序员是否犯了这个错误。

当函数的返回类型为引用时候,不要返回一个临时变量的引用

6.关于对象的引用

对于基类和派生类来说,基类的引用可以指向派生类的引用,而且无需进行类型转换。

7.使用引用的原因

(1)程序员能够修改调用函数里的数据对象

(2)通过传递引用而不是整个数据对象,可以提高程序的运行速度。

8.引用、指针、值的使用情况

数据对象比较小,采用按值传递。

对象是数组或者结构,采用指针。

类对象,采用引用。

9.默认参数

C++允许函数使用默认参数,例如fun(int a,int b=0);

这样意味着你可以这样调用fun函数:fun(1),b被默认初始化为0了,如果你不想使用默认的b值,则可以这样fun(1,2);

注意事项:必须从右往左添加默认值,例如 fun(int a,int b=1,int c=2)

对于 fun2(int a=1,int b=2,int c=3)

不允许这样调用 fun2(1,,4);

10.函数重载

函数重载的关键在于函数的参数列表。也称为函数的特征标,特征标包含 函数的参数数目,类型,参数的排列顺序。

只有当函数的特征标不同时候,才可以实现函数重载

类型引用和类型本身视为同一个特征标

就是说print(int &i)和print(int i)无法重载,编译器无法决定使用哪一个。

函数的特征标相同但函数的返回类型不同的函数也无法重载

如long fun(int i)和 int fun(int i)

函数重载的实现:C++编译器执行神奇的操作——名称修饰,会根据函数原型中指定的形参类型对每个函数名进行加密,也就是说即使函数名相同,如果函数特征标不同的话,编译器编译出来的函数们,它们的名称是不同的,这样在调用的时候,程序会根据参数类型去找正确的函数。

注意:一个函数既不能作为重载函数,又作为有默认参数的函数

因为,如果调用的时候少写一实参,系统无法判断是利用重载函数还是默认参数的函数

11.函数模板

什么时候使用模板?

如果需要多个将同一种算法应用于不同种类型的函数,请使用模板

对于某些功能相同的函数,如果他们的参数个数相同,可以使用模板

语法:template

函数类型 函数名 函数参数

例如:

template

void swap(T &a,T&b)

{

  T  t=a;

  a=b;

  b=t;

}

程序执行时候会根据函数模板和给定参数类型去生成一个给定参数类型的函数。

显示具体化

当编译器找到与函数调用匹配的具体化定义时,将使用该定义,而不再寻找模板。

什么时候用显示具体化呢,举个例子,当我们在使用上述swap函数模板交换结构体的时候,我们希望几交换结构体中的某个数据对象,而不交换其他数据对象,这时候就可以使用显示具体化。

struct job
{
    string name;
    double salary;
    int floor;
};

template<>
void Swap<job>(job &j1,job &j2)//只交换薪水
{
    double t1;
    t1=j1.salary;
    j1.salary=j2.salary;
    j2.salary=t1;
}

还有一个叫显示实例化的东西,就是说你告诉编译器,让编译器提前生成一个类型的函数

如 template void swap(int,int );这是个声明

所谓隐式实例化就是程序根据参数类型来生成函数。

显示实例化 隐式实例化 显示具体化统称为具体化

编译器选择使用哪一个函数版本

第一步:创建候选函数列表。其中包含与被调函数名称相同的函数和模板函数

第二步:使用候选函数列表创建可执行函数。

第三步:确定是否有最佳的可行函数。

从最佳到最差的顺序为:

1.完全匹配

2.提升转换(如 shorts 转换为 int ,float转换为double)

3.标准转换(如char 转换为int,long转换为double)

4.用户定义的转换(如类声明里定义的转换)

选择使用函数模板还是函数重载?

如果函数的函数体和参数个数相同,那么则可使用函数模板,反之则使用函数重载

C++ Primer Plus第六版第八章函数探幽编程练习答案 1. #include<iostream> using namespace std; void show(const char *str, int n = 0); int main() { char str[20]; int n; cout << "输入一个句子: "; cin.getline(str, 20); cout << "输入打印次数: ";... 阅读详情

相关推荐

从报错到优化:一次Gauss JDBC参数限制排查实录(32767参数上限避坑指南)

本文详细记录了排查GaussDB JDBC驱动因绑定参数数量超过32767上限而抛出`PSQLException`(报错信息为`Tried to send an out-of-range integer as a 2-byte value`)的全过程。文章深入分析了该限制的底层协议原理,并提供了应用层分批查询、使用临时表以及优化业务逻辑等多种解决方案,旨在帮助开发者规避此参数上限陷阱,构建更稳健的数据访问层。

rgv23456789的博客 218

C++学习之路(七),C++primer plus 第八章 函数探幽

**第 8 章 函数探幽** 本章内容包括: 内联函数。 引用变量。 如何按引用传递函数参数。 默认参数。 函数重载。 函数模板。 函数模板具体化。 通过第 7 章,了解到很多有关 C++ 函数的知识,但需要学习的知识还很多。C++ 还提供许多新的函数特性,使之有别于 C 语言。新特性包括内联函数、按引用传递变量...

hsoftk的博客 969

超级详细!!!新手使用AutoDL跑深度学习(MixVPR项目)的学习记录

新手第一次在AutoDL上跑深度学习的实验,遇到一些问题,简单记录一下。如果大家发现问题,欢迎和我讨论。

weixin_45152283的博客 5万+

C++ Primer Plus 随记(第八章)函数探幽

1、内联函数:编译器将使用相应的代码替换函数调用。 --优点:运行速度稍快 --缺点:代码膨胀 内联函数:一、在函数声明前加上关键字inline;二、在函数定义前加上关键字inline。 无法作为内联函数的原因:一、内联函数不能递归;二、函数体过大。 内联与宏: C语言使用预处理器语句 #define 提供宏--内联代码的原始实现(实际上使用 文本替换来实现)。 #define SQUARE(X) ((X)*(X)); 使用c语言的宏执行可以考虑利用C++内联函数进行替...

Baimax的博客 322

Netapp FAS2750热备盘替换失败问题分析与解决

本文深入分析了Netapp FAS2750存储系统中热备盘替换失败的故障现象,揭示了磁盘分区属主不匹配导致数据同步无法启动的根本原因。通过详细的排查步骤和解决方案,帮助运维人员快速恢复aggr状态,并提供了长期预防措施和最佳实践建议,确保存储系统的高可用性。

weixin_33737774的博客 399

保姆级避坑指南:Mid-360雷达到手后,用livox_ros_driver2从接线到出点云的完整流程

本文提供Mid-360雷达到手后的完整使用指南,涵盖从硬件接线、网络配置到livox_ros_driver2驱动的安装与调试,帮助用户避开常见陷阱,实现点云数据的稳定输出与可视化。重点解析了配置文件的参数设置和点云格式选择,确保用户能够高效部署和使用Mid-360雷达。

weixin_30733003的博客 484

C++ primer plus 第六版 第八章 编程练习答案

第八章 编程练习答案 1. 一开始没看懂题目意思,百度参考了一下别人的结果。 #include &lt;iostream&gt; using namespace std; int count = 0; void Printf(const char * str, int n = 0);//默认参数 int main() { const char* str = "hello!"...

菜鸡harry的博客 5651

倾斜摄影与地面激光点云融合高精度建模研究

本文研究了倾斜摄影与地面激光点云融合精细化建模技术,并通过相应的源代码实现了建模过程。该方法将倾斜摄影和激光扫描相结合,能够获得高精度的三维建模结果,为相关领域的研究和应用提供了有力支持。近年来,倾斜摄影和激光扫描技术的快速发展为高精度三维建模提供了新的机遇和挑战。本文针对倾斜摄影与地面激光点云融合建模这一前沿领域展开研究,旨在通过相应的源代码实现精细化的建模过程。同时,使用激光扫描仪进行地面激光扫描,获取地面的点云数据。经过数据融合和精细化建模处理后,我们获得了高精度的三维建模结果。

LpmShell的博客 1245

C++ Primer Plus第八章 函数探幽

首先,书上是这么讲的:编译过程的最终产品是可执行程序——由一组机器语言指令组成。运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。计算机随后将逐步执行这些指令。有时(如有循环或分支语句时),将跳过一些指令,向前或向后跳到特定地址。常规函数调用也使程序跳到另一个地址(函数的地址),并在函数结束时返回。下面更详细地介绍这一过程的典型实现。

github_59710496的博客 932

Go语言爬虫:chromedp 的详细使用

chromedp 是 Go 语言中无头浏览器自动化的终极利器。它能驱动真实的 Chrome 浏览器,处理 JavaScript 渲染、复杂交互和反爬虫机制

数据知道的博客 4492

2025秋招LLM大模型多模态面试题(八)- langchain完整面试题

1. **什么是 LangChain** 2. **LangChain 包含哪些核心模块** - 模型输入/输出(Model I/O) - 组件管理 - 数据处理 - 链式组合 - 记忆与上下文管理 - 外部集成 3. **一些核心概念** 4. **什么是 LangChain Agent?** 5. **什么是 LangChain model?** 6. **LangChain 包含哪些特点?** 7. **LangChain 如何使用?** - LangChai

weixin_41496173的博客 2192

【C++ Primer Plus】第八章:函数探幽

个人笔记总结

Friday 646

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C++ Primer Plus: 第八章 函数探幽

C++ Primer Plus: 第八章 函数探幽 8.1 C++内联函数 内联函数是C++为提高程序运行速度所做的一项改进。常规函数和内联函数之间的主要不在于编写方式,而在于C++编译器如何将它们组合到程序中。 编译过程的最终产品是可执行程序——由一组机器语言指令组成。 执行到函数调用指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数参数赋值到堆栈,跳到标记函数起点的内存单元...

budding0828 684

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

《Cpp-Primer-Plus》-第八章 函数探幽

第八章 函数探幽 博文地址 本文记录CCPlus第八章知识 知识整理 c++在函数方面,相比于c,还有许多新特性,如内联函数,按引用传递变量,默认的参量值,函数重载和模版函数 内联函数 ​ 要知道内联函数与普通函数的区别,就要弄清楚两者调用的区别。 ​ 普通函数调用使程序跳到另一个地址,即函数开头地址执行,并在函数结束时返回,来回跳跃并记录跳跃位置需要一定的开销,而内联函数不需要跳到另一个位置处执行代码,它是使编译器使用相应的函数代码替换函数调用,所以它的运行速度比普通函数快,但代价是需要占用更多的内存。

小菜鸟博客 312

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C++ primer plus 第八章函数探幽总结

引用变量 它实质上是变量的别名,我们可以看作他是变量的一个“外号” 创建方法 int rats; int &amp;rodents=rats;(必须在声明的时候就初始化,不可int &amp;rodents;rodents=rats;) 在这里rodents与rats指向相同的内存单元与值。也就是说,rats与rodents 的值都相同 引用变量作为函数参数 引用变量作为函数参数的参...

weixin_41271939的博客 243

《C++ primer plus》第八章:函数探幽

内联函数、引用、默认参数、函数重载、函数模板

weixin_40064300的博客 617

「C++」C++ Primer Plus 笔记:第八章 函数探幽

通过将类型作为参数传递给模版,可使编译器生成该类型的函数。**使用模板可以定义类或函数的操作,并让用户指定这些操作应处理的具体数据类型。**例如,对某个类型的数据的两个值进行交换,下次又需要对另一个类型的数据值进行交换,那么此时定义一个模版,就可以在调用交换数据功能时,提供被交换数据的数据类型,从而不用重新针对不同数据类型写同样功能的函数。

Liiipseoroinis 332

《C++ Primer Plus》 第八章 函数探幽

第八章 函数探幽 inline内联函数 内联函数是C++为提高程序运行速度所做的一项改进。 内联函数的一般写法是,省略函数原型,将整个定义放在函数原型的位置,并在函数返回值类型前加上inline。 内联函数一般适用于调用频繁但函数体简单的函数。 引用变量 引用变量的主要作用是用作函数的形参,使得函数使用原始数据而不是副本,达到和指针类似的效果。 创建引用变量: int rats; int &amp...

NiuJuxin的博客 219

C++ Primer Plus 第八章 函数探幽

C++ primer plus 学习记录

weixin_43753276的博客 352

第八章(函数探幽 )——C++ Primer Plus

复习笔记

m0_56378800的博客 548

[C++ primer plus]第八章 函数探幽

函数模板 显示具体化 显示实例化 隐式实例化 decltype关键字 右值引用 内联函数

qq_38107043的博客 375

C++ Primer Plus学习笔记-第八章:函数探幽

第八章:函数探幽 内联函数是C++为提高程序运行速度而做的一项改进,它的原理是:像C语言中的宏替换那样直接将函数代码插入调用它的位置并直接编译,好处是不需要像常规函数调用一样来回切换执行位置,缺点是一个内联函数需要拷贝多个副本;当函数调用相当频繁时使用内联函数效果更明显; 使用内联函数的条件: 在函数声明前加上关键字inline 在函数定义前加上关键字inline 注意:内联函数不能递归 引用是已定义变量的别名,主要用途是作为被调用函数的形参,这样被调用的函数就可以直接使用原始数据; C和C++使用符号

m0_55639846的博客 369

《C++ primer plus》学习笔记——第八章函数探幽

文章目录一、C++内联函数 一、C++内联函数 (1)C++区别于C语言,提供了新特性:内联函数,引用传递变量,默认的参数值,函数重载(多态)以及模板函数; (2)C++内联函数的优势: (3)写内联函数的要求: (a)在函数声明前加上关键字inline; (b)在函数定义前加上关键字inline; (c)内联函数不能递归 (4)什么时候用内联函数呢? 代码量不多,且经常使用 (5)eg如下:...

喜欢打篮球的普通人 1017

【C++ Primer plus】【第八章】函数探幽

本章主要涉及引用,重载,模板三个方面 【引用】 1.内联函数不能递归 2.引用是已经定义好变量的别称,其作用是不再是值传递的副本,而是数据本身。 3.必须在声明引用变量时初始化,其伪代码类似于int * const型,可以改变其值 4.引用的函数声明 int swap(int &a,int &b) 5.引用参数是const条件下,有两种情况会产生临时变量 类型正确,但不是左值; 类

Ezio_Auditore_的博客 343
上一篇: 全加器以及行波进位器的延迟时间计算
下一篇: C++ primer Plus 第九章:内存模型和名称空间
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值