正文
Part2:函数重载
1.一个引子
从自然语言开始吧,比如中文:
自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。
🌰比如:
以前有一个笑话,中国有两个体育项目大家根本不用看,也不用担心。
一个是乒乓球,一个是男足。
前者是“谁也赢不了!”,后者是“谁也赢不了!”
🪄嘿,“谁也赢不了!”这句话,我不用解释你也知道它的双重意思,“谁也赢不了!”这句话就被重载了。
2.概念
自然语言有重载,像C++这样的计算机语言中也有函数重载:
C++允许在同一作用域中声明几个功能类似的同名函数。
只要满足下列一个条件就能满足函数重载:
①参数类型不同
②参数个数不同
③参数顺序不同
🌰例子:
#include<iostream> using namespace std; // ① 参数类型不同 int Add(int x, int y) { cout << "int Add(int x, int y)" << endl; return x + y; } double Add(double x, double y) { cout << "double Add(double x, double y)" << endl; return x + y; } int main() { cout << Add(3, 5) << endl; cout << Add(3.1, 5.2) << endl; return 0; }
👁️🗨️输出结果:
(这种类型适用了不同数据类型的加法)
// ② 参数个数不同 void f() { cout << "f()" << endl; } void f(int a) { cout << "f(int a)" << endl; } int main() { f(); f(10); return 0; }
👁️🗨️输出结果:
// ③ 参数类型顺序不同 void f(int a, char b) { cout << "f(int a,char b)" << endl; } void f(char b, int a) { cout << "f(char b, int a)" << endl; } int main() { f(10, 'c'); f('c', 10); return 0; }
👁️🗨️输出结果:
3.不支持函数重载
以下情况不支持函数重载:
①函数返回值不同
②函数省缺值不同
③调用存在歧义
函数返回值不同:
#include <iostream> using namespace std; int func(int x) { ; } double func(int x) { ; } int main() { func(3); // 不知道这里是调用 int func 还是 double func return 0; }
👁️🗨️结果:
这个还好理解,在调用的时候区别不开返回类型
#include <iostream> using namespace std; void func(int a) { cout << "func(int a)" << endl; } void func(int a = 10) { cout << "func(int a)" << endl; } int main() { func(1); return 0; }
👁️🗨️结果:
调用存在歧义:
#include <iostream> using namespace std; void func() { cout << "func()" << endl; } void func(int a = 0) { cout << "func(int a)" << endl; } int main() { func(); // 调用存在歧义 func(1); // 可以正常调用 return 0; }
👁️🗨️结果:
Part3:内联函数
1.概念
内联内联,单看这个名字的却没什么概念,这里就直接告诉你吧:
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,
没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
众所周知,普通的函数调用都是需要建立栈帧的,
存在这种情况:需要频繁调用的函数,并且函数本身代码量不多,那么就可以利用内联函数,加个 inline,展开后就没有函数调用建立栈帧的开销了。
🌰例子:
#include <iostream> using namespace std; inline int Add(int x, int y) { return x + y; } int main() { int ret = Add(3, 5); return 0; }
转到反汇编,就不会看到call指令了
2.特性
我们来客观的分析一下内联函数的特性:
inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用;
缺陷:可能会使目标文件变大;
优势:少了调用开销,提高程序运行效率。
inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同;
一般建议:将函数规模较小、不是递归、频繁调用的函数采用inline修饰
🪄程序员不小心,还有编译器挡着嘛,如果你把太长的函数内联了,编译器受不了的~
它大概率会忽略内联请求。
inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
总结:
本期继续带大家学习C++,知识点有:省缺参数 | 函数重载 | 内联函数,主要是针对函数的。