C++学习总结7--函数

小记:静默如初,安之若素

1.函数重载

  1. 定义
     在相同的作用域,定义同名的函数,但是它们的参数要有所区分,这样的多个函数构成重载关系。
     注:函数的重载和返回值无关
eg: 图像库(包含很多绘图函数)
//C语言实现(C语言不能有同名函数)
 void drawCircle(int x, int y, double r){...}
 void drawRect(int x, int y, double w, double h){...}
 ...
//C++语言实现
 void draw(int x, int y, double r){...}
 void draw(int x, int y, double w, double h){...}
 ...
  1 #include <iostream>
  2 using namespace std;
  3 
  4 int foo(int a)
  5 {
  6   cout<<"foo(int)"<<endl;
  7 }
  8 
  9 void foo(int a, int b)
 10 {
 11   cout<<"foo(int, int)"<<endl;
 12 }
 13 
 14 void foo(int a, float b)
 15 {
 16   cout<<"foo(int, float)"<<endl;
 17 }
 18 
 19 int main(int argc, char * argv[])
 20 {
 21   foo(10);//foo(int)
 22   foo(10, 20);//foo(int, int)
 23   //foo(10, 3.14); //直接传实参3.14出错,实参默认为double
 24                  //error: call of overloaded ‘foo(int, double)’ is ambiguous
 25   foo(10, 3.14f);//标明格式就可以. foo(int, float)
 26 
 27   //通过函数指针调用重载关系的函数,
 28   //实际调用哪个版本是由指针类型决定,而不是由实参类型决定。
 29   void (*pfoo)(int, float) = foo;
 30   pfoo(10, 20); // foo(int, float);
 31   return 0;
 32 }
~     
  1. 函数重载匹配(编译器决定)
    调用重载关系的函数时,编译器将根据实参与形参的匹配程度(内存),自动选择最优的版本。
    当前g++编译器的一般匹配规则:
 完全匹配 >= 常量转换 > 升级转换 > 降级转换 > 省略号匹配
  1 #include <iostream>
  2 using namespace std;
  3 
  4 //char --> int ::升级转换(内存浪费)
  5 void bar(int i)
  6 {
  7   cout <<" bar(1)"<< endl;
  8 }
  9 //char --> const char : 常量转换
 10 void bar(const char c)
 11 {
 12   cout <<" bar(2)"<< endl;
 13 }
 14 
 15 //short(2 byte) --> char(1 byte) : 标准转换(降级转换)
 16 void fun(char c)//char 1 byte
 17 {
 18   cout<<" fun(1) "<<endl;
 19 }
 20 //short(2 byte) --> int(4 byte) : 升级转换
 21 void fun(int i)//int 4 byte
 22 {
 23   cout<<" fun(2) "<<endl;
 24 }
 25 
 26 //省略号匹配
 27 void hum(int i, ...)//...可变长参数
 28 {
 29   cout<<" hum(1) "<<endl;
 30 }
 31 
 32 //double(8 byte) --> int(4 byte) : 降级转换
 33 void hum(int i, int j)
 34 {
 35   cout<<" hum(2) "<<endl;
 36 }
 37 
 38 
 39 int main(int argc, char * argv[])
 40 {
 41   //常量转换优先级高于升级转换
 42   char c = 'A';
 43   bar(c);//bar(2)
 44 
 45   //在数据转换时,数据的完整型优先级高于内存的使用
 46   short s = 10;
 47   fun(s);//fun(2)
 48 
 49   //数据转换时:优先确定类型的转换
 50   hum(10, 3.14);//hum(2)
 51 
 52   return 0;
 53 }
  1. 函数重载实现原理
    C++编译器是通过对函数进行换名,将参数表信息整合到新的名字中,实现解决函数重载和名字冲突的问题。
    笔试题:C++中 extern “C” 的作用?
    答案:在C++函数声明的前面加入extern “C”, 要求C++编译器不对该函数换名,方便C程序直接调用。
    注:extern “C” 声明的函数无法重载。

2 函数的哑元参数

  1. 定义
    只有类型没有形参变量名的参数成为哑元
void func(int /*哑元*/){}
  1. 使用哑元的特征场景
    1)兼容旧代码
eg: 算法库
 void video_func(int a, int b){...}
 使用者:
 int mian(void)
 {
 	video_func(10, 20);
 }
 ----------------------
 升级了算法库:void video_func(int a, int/*哑元*/){...}
 使用者:
 int main(void)
 {
 	video_func(10, 20)
 }

2)操作符重载中区分前后++/–

3.函数缺省参数(默认参数)

  1. 可以在声明函数时,为它的部分或全部参数指定缺省值,在调用该函数时,如果不给传递实参,就取缺省值作为相应形参的值。
eg:
void func(int a, int b = 0){}
func(100, 0);
func(100);//与上面的调用等价
  1. 缺省参数必须靠右,如果函数的一个参数带有缺省值,那么该函数的右侧所有参数都必须带有缺省值。
eg:
	void func(int a = 0, int b){}//error
	void func(int b, int a = 0){}//true
  1 #include <iostream>
  2 using namespace std;
  3 
  4 void foo(int a, int b = 20, int c = 30)
  5 {
  6   cout<< a << " , " << b << " , " << c <<endl;  
  7 }
  8 
  9 //缺省参数声明必须靠右写(靠右原则)
 10 //error: default argument missing for parameter 2 of ‘void foo1(int, int, int)’ 
 11 /*
 12 void foo1(int a = 10, int b, int c = 30)
 13 { 
 14   cout<< a << " , " << b << " , " << c <<endl;  
 15 }
 16 */
 17 
 18 int main(int argc ,char* argv[])
 19 { 
 20   foo(1, 2, 3);// a 1, b 2, c 3;
 21   foo(1, 2); // a 1, b 2, c 30;
 22   foo(1); //a 1, b 20, c 30;
 23   return 0;
 24 }

  1. 缺省参数使用时注意重载时可能存在歧义问题;如果一个函数定义和声明分开,缺省参数写在函数声明部分,定义部分不写。
eg:
  void func(缺省参数);//声明
  void func(){...}//定义
  1 #include <iostream>
  2 using namespace std;
  3 
  4 //函数声明
  5 void foo(int a, int b = 20, int c = 30);
  6 //void foo(int a, int = 20, int = 30);//true
  7 
  8 //注意重载函数时的歧义错误
  9 //void foo(int x){}
 10 
 11 int main(int argc, char* argv[])
 12 { 
 13   foo(1, 2, 3);// a 1, b 2, c 3;
 14   foo(1, 2); // a 1, b 2, c 30;
 15   foo(1); //a 1, b 20, c 30;
 16   return 0;
 17 }
 18 //函数定义
 19 void foo(int a, int b/*= 20*/, int c/* = 30*/)
 20 { 
 21   cout<< a << " , " << b << " , " << c <<endl;
 22 }

4 内联函数(inline*)

  1. 定义:
    使用inline修饰的函数,表示这个函数是内联函数,编译器将会尝试做内联优化,减小函数调用的开销(空间换时间)。
    笔试题:inline 关键字的作用?(定义)
  2. 适用场景
    1)多次调用小而简单的函数适合内联;
    2)调用次数极少或者大而复杂的函数不适合内联;
    3)递归函数不能内联;
    注:内联只是一种建议而不是强制要求,一个函数能否内联优化主要取决于编译器,有些函数不加inline修改也会被编译器默认处理为内联优化,有些函数即使加了inline关键字也会被编译器忽略。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值