C++的函数

八、C++的函数

1、函数重载
1)定义:在相同作用域,定义同名的函数,但是它们的参数要有所区分,这样的多个函数构成重载关系。
注:函数的重载和返回值无关

eg:图形库(包含很多绘图函数)
//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){//.....}

overload.cpp

#include <iostream>
using namespace std;

int foo(int a){
	cout << "foo(int)" << endl;
	return 0;
}

void foo(int a, int b){
	cout << "foo(int, int)" << endl;
}

void foo(int a, float b){
	cout << "foo(int, float)" << endl;
}

int main(void){
	foo(10);
	foo(10, 20);
	foo(10, 3.14f);
	//通过函数指针调用重载关系的函数,实际调用哪个版本由指针类型决定,
	//而不是由实参类型决定
	void (*pfoo)(int, float) = foo;
	pfoo(10,20);//foo(int, float)
	return 0;
}

2)函数重载匹配
overload.cpp

#include <iostream>
using namespace std;

//char-->int:升级转换
void bar(int i){
	cout << "bar(1)" << end;
}

//char-->const char:常量转换
void bar(const char c){
	cout << "bar(2)" << end;
}

//short-->char:降级转换
void fun(char c){
	cout << "fun(1)" << endl;
}

//short-->int:升级转换
void fun(int i){
	cout << "fun(2)" << endl;
}

//省略号匹配
void hum(int i, ...){
	cout << "hum(1)" << endl;
}

//double-->int:降级转换
void hum(int i, int j){
	cout << "hum(2)" << endl;
}
int main(void){
	char c = 'A';
	bar(c);//bar(2)
	short s = 10;
	fun(s);//fun(2)
	hum(10, 3.14);//hum(2)
	return 0;
}

调用重载关系的函数时,编译器将根据实参与形参的匹配过程度,自动选择最有的版本。
当前g++编译器的一般匹配规则:完全匹配>=常量转换>升级转换>降级转换>省略号匹配

3)函数重载实现原理
C++编译器是通过对函数进行换名,将参数表信息整合到新的名字中,实现解决函数重载和名字冲突的问题。

笔试题:C++中extern“C”的作用?
答:在C++函数声明前面加入extern “C”,要求C++编译器不对该函数进行换名,
方便C程序直接调用。当然这样就不能实现函数重载。

2、函数的哑元参数
1)定义:只用类型而没有形参变量名的参数称为哑元。
void func(int /哑元/){ }

2)使用哑元的特殊场景:
–》兼容旧代码
eg:算法库
void video_func(int a, int b){…}
--------------------------------------
升级了算法库:void video_func(int a, int){…}
使用者:
int main(void){
vedio_func(10, 20);
}
以上例子意思是原来的程序需要两个形参,但是当程序升级之后只要一个形参就能完成原来的操作。而这时候客户那边就要更改原来的程序,这样做会很麻烦,而且成本很大。这时候开发者就要使用哑元,避免客户那边更改程序,从而节省升级成本。

3、函数缺省参数(也称为默认实参)
1)可以在声明函数时,为它的部分或全部参数指定缺省值,在调用
该函数时,如果不给传递实参,就取缺省值作为相应形参的值。
eg:
void func(int a, int b = 0){…}
func(100, 0);
func(100);

defArg.cpp

#include <iostream>
using namespace std;

//函数声明
void foo(int a, int b=20, int c=30);//缺省值应该写在声明中

void foo(int a, int b = 20, int c  = 30){//缺省值必须靠右
	cout << a << "," << b << "," << c << endl;
}
//注意歧义错误
//void foo(int x){}//如果这个函数存在,编译foo(1)时会发生错误

int main(void){
	foo(1, 2, 3);//1,2,3
	foo(1, 2);//1,2
	foo(1);//1
	return 0;
}

2)缺省参数必须靠右,如果函数的一个参数带有缺省值,那么该函数的右侧参数都必须带有缺省值。
eg: void func(int a =0, int b){}//error
void func(int b, int a = 0){}//ok

3)如果函数的定义和声明分开,缺省参数应该写在函数的声明部分,而定义部分不写。
eg:
void func(缺省参数);//声明
void func(){}//定义

笔试题:inline关键字作用?
4、内联函数(inline)
1)定义:使用inline关键字修饰的函数,表示这个函数时内联函数,编译器将会
尝试做内联优化,减小函数调用的开销。(节省函数多次调用外部函数跳转时间)

2)内联函数使用情况
–》多次调用小而简单的函数适合内联
–》调用次数极小或者大而复杂的函数不适合内联
–》递归函数不能内联

注:内联只是一种建议而不是强制要求,一个函数能否内联优化主要取决于编译器,有些函数不加inline修饰也会被编译器默认处理为内联优化,有些函数即使被inline修饰也会被编译器忽略掉。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值