| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 第 8 章 函数探幽 -> 正文阅读 |
|
[C++知识库]第 8 章 函数探幽 |
本章内容包括:
8.1 C++内联函数内联函数是C++为提高程序运行速度所做的一项改进。常规函数和内联函数之间的主要区别不在于编写方式,而在于C++编译器如何将它们组合到程序中。要了解内联函数与常规函数之间的区别,必须深入到程序内部。 编译过程的最终产品是可执行程序——由一组机器语言指令组成。运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。计算机随后将逐步执行这些指令。有时(如有循环或分支语句时),将跳过一些指令,向前或向后跳到特定地址。常规函数调用也使程序跳到另一个地址(函数的地址),并在函数结束时返回。更详细的介绍这一过程的典型实现: 执行到函数调用指令时,程序将在函数调用后立即执行该指令的内存地址,并将函数复制到堆栈,跳到标记函数起点的内存单元,执行函数代码,然后跳回到地址被保存的指令处。来回跳跃并记录跳跃位置意味着以前使用函数时,需要一定的开销。 C++ 内联函数提供了另一种选择。内联函数的编译代码与其他程序代码“内联”起来了。也就是说,编译器将使用相应的函数代码替换函数调用。对于内联代码,程序无需跳到另一个位置处执行代码,再调回来。因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存。如果程序在10个不同的地方调用同一个内联函数,则该程序将包含该函数代码10个副本。 应有选择的使用内联函数,如果执行代码的时间比处理函数调用机制的时间长,则节省的时间将只占整个过程很小一部分。如果代码执行的时间很短,则内联调用就可以节省非内联调用使用的大部分时间。另一方面,由于这个过程相当快,因此尽管节省了该过程的大部分时间,但节省的时间绝对值并不大,除非该函数经常被调用。 内联函数的特性,
通常的做法是省略原型,将整个定义(即函数头和所有函数代码)放在本应提供原型的地方。 程序员请求将函数作为内联函数时,编译器并不一定会满足这种请求。它可能认为该函数过大或注意到函数调用了自己(内联函数不能递归),因此不将其作为内联函数;而有些编译器没有启用或实现这种特性。
程序输出如下,输出表明,内联函数和常规函数一样,也是按值来传递参数的如果参数为表达式,如4.5+7.5,则函数将传递表达式的值。 内联与宏 ?inline工具是C++新增的特性。C语言使用预处理器语句#define来提供宏——内联函数的原始实现。 如下,并不是通过传递参数实现,而是通过文本替换来实现的,X 是“参数”的符号标记。只有第一个a能正常工作。 8.2 引用变量8.2.1 创建引用变量前面讲过,C和C++使用&符号来指示变量的地址。C++给&符号赋予了另一个含义,将其用来声明引用。例如将rodents作为rats变量的别名,你可以这样做:
其中,&不是地址运算符,而是类型标识符的一部分。就像声明中的char* 指的是指向char的指针一样, int &指的是指向int的引用。 引用有些类似于指针,但是还是不同于指针,除了表示法不同外,还有其他的差别,例如必须在声明引用时将其初始化,而不能像指针那样,先声明,再赋值:
引用更接近const指针,必须在创建时进行初始化,一旦与某个变量关联起来,就将一直效忠于它。 8.2.2 将引用用作函数参数引用经常被用作函数参数,使得函数中的变量名成为调用程序中的变量的别名。这种传递参数的方法称为按引用传递。按引用传递允许被调用的函数能够访问调用函数中的变量。C++新增的这项特性是对C语言的超越,C语言只能按值传递。按值传递导致被调用函数使用调用程序的值的拷贝。当然,C语言也允许避开按值传递的限制,采用按指针传递的方式。
如上是按引用,指针,值作为参数传递的方式,引用和指针都成功地交换了两个钱夹的内容,而按值传递的方法没能完成这项任务。 8.2.3 引用的属性和特别之处引用传递时候,不允许引用函数内改变引用地址的值。
临时变量、引用参数和const 如果实参与引用参数不匹配,C++将生成临时变量。当前,仅当参数为const引用时,C++才允许这样做。 尽可能的使用const
8.2.4 将引用用于结构引用非常适合用于结构和类。使用结构引用参数的方式与使用基本变量引用相同,只需要在声明结构参数时使用引用运算符&即可。
返回引用时,要避免返回函数终止时不再存在的内存单元引用。 8.2.5 将引用用于类对象将类对象传递给函数时,C++通常的做法时使用引用。 8.2.6 对象、继承和引用ostream和ofstream类凸显了一个有趣属性,ofstream对象可以使用ostream类的方法,这使得文件输入/输出的格式与控制台输入/输出相同。使得能够将特性从一个类传递给另一个类的语言特性称为继承。ostream是基类,ofstream是派生类。派生类继承了基类的方法。 继承的另一个特征是, 基类引用可以指向派生类对象,而无需进行强制类型转换。这种特征的一个实际结果是,可以定义一个接受基类引用作为参数的函数,调用该函数时,可以将基类对象作为参数,也可以将派生类对象作为参数。 8.2.7 何时引用参数使用引用参数的主要原因有两个。
当数据对象较大时(如结构和类对象),第二个原因最重要。这些也是使用指针参数的原因。因为引用参数实际上是基于指针的代码的另一个接口。 对于使用传递的值而不作修改的函数。
对于修改调用函数中数据的函数:
8.3 默认参数对于带参数列表的函数,必须从右向左添加默认值。也就是说,要为某个参数设置默认值,则必须为它右边的所有参数提供默认值。 实参按从左到右顺序依次被赋给相应的形参,而不能跳过任何参数。 8.4 函数重载函数多态是C++在C语言的基础上新增的功能。默认参数能让您使用不同数目的参数调用同一个函数,而函数多态(函数重载)让您能够使用多个同名的函数。 函数重载的关键是函数的参数列表——也称为函数特征标。如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则它们的特征标相同,而变量名是无关紧要的。C++允许定义名称相同的函数,条件是它们的特征标不同。如果参数数目或参数类型不同,则特征标也不同。
是特征标,而不是函数类型使得可以对函数进行重载。例如,下面的两个声明是互斥的:
8.4.1?何时使用函数重载虽然函数重载很吸引人,但也不要滥用。仅当函数基本上执行相同的任务,但使用不同形式的数据时,才应采用函数重载。另外您可能还想知道,是否可以通过使用默认参数来实现同样的目的。例如,可以用两个重载函数来代替面向字符串的left()函数:
使用一个带默认参数的函数要简单些。只需编写一个函数(而不是两个函数),程序也只需为一个函数(而不是两个)请求内存;需要修改函数时,只需要修改一个。然而,如果需使用不同类型的参数,则默认参数不管用了,在这种情况下,应该使用函数重载。 8.5 函数模板现在的C++编译器实现了C++新增的一项特性——函数模板。函数模板是通用的函数描述,也就是说它们使用泛型来定义函数,其中的泛型可用具体的类型(如int,double)替换。由于类型是用参数表示的,因此模板特性有时也被称为参数化类型。 之前定义了一个交换两个int值得函数,假设要交换两个double值,则一种方法是复制原来的代码,并用double替换所有int。但是这种方法容易出错,如用全局查找和替换,将double替换int,可能将:
转换为:
C ++的函数模板功能能自动完成这一过程,可以节省时间,且更可靠。 函数模板允许以任意类型的方式来定义函数。例如,可以建立一个交换模板:
第一行指出,要建立一个模板,并将类型命名为AnyType。关键字template和typename是必需的,除非可以使用关键字class代替typename。另外,必须使用尖括号。类型名可以任意选择(这里为AnyType)。只要遵守C++命名规则即可,许多程序员都使用简单的名称,如T。余下的代码描述了交换两个AnyType值得算法。模板并不创建任何函数,而只是告诉编译器如何定义函数。需要交换int得函数时,编译器将按模板模式创建这样得函数,并用double代替AnyType。 在标准C++98添加关键字typename之前,C++使用关键字class来创建模板。也即是说,可以这样编写模板定义,typename关键字使得参数AnyType表示类型这一点更为明显。
8.5.1 重载的模板需要多个对不同类型使用同一算法的函数时,可使用模板。然而,并非所有的类型都使用相同的算法。为满足这种需求,可以像重载常规函数定义那样重载模板定义。和常规重载一样,被重载的模板的函数特征标必须不同。并非所有的模板参数都必须时模板参数类型。
8.5.2 模板的局限性8.5.3 显式具体化8.5.4 实例化和具体化8.5.5 编译器选择使用哪个函数版本8.5.6 模板函数的发展8.6 总结 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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年12日历 | -2024/12/27 21:06:46- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |
数据统计 |