天天看点

C++学习之函数重载、哑元参数、缺省参数、内联函数

  1. 函数重载

    1)定义

    在相同作用域,定义的同名函数,但是它们的参数必须有所区分,这样的函数将构成重载关系

    注:函数能否重载和返回类型无关.

    #include <iostream>
    
    using namespace std;
    
    void func(int i){
    	cout << "func(int)" << endl;
    }
    void func(int a, int b){
    	cout << "func(int ,int)" << endl;
    }
    void func(int a, float b){
    	cout << "func(int ,float)" << endl;
    }
    
    int main(void){
    	func(10);
    	func(10, 20);
    	func(10, 1.23f);//1.23后边必须加f
    	void (*pfunc)(int, float) = func;//定义一个返回值为空,参数为int,float的函数指针,将func
    									//赋值给它,实际上将第三个函数传递给func
    	pfunc(10,20);//并不会调用第一个,而是调用第三个
    	return 0;
    }
               

    2)函数重载匹配

    调用重载关系的函数时,编译器会根据实参与形参的匹配程度,自动选择最优匹配版本,当前g++编译器匹配一般规则:

    完全匹配>=常量转换>升级转换>降级转换>省略号匹配

    #include <iostream>
    
    using namespace std;
    
    //char -> int:升级转换
    void bar(int i){
    	cout << "bar(1)" << endl;
    }
    
    //char -> const char:常量转换
    void bar(const char c){
    	cout << "bar(2)" << endl;
    }
    
    //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);
    	short s = 10;
    	fun(s);
    	hum(10, 1.23);
    	return 0;
    }
               

    3)函数重载原理

    C++编译器是通过对函数进行换名,将参数表的类型整合到新的函数名中,解决函数重载和名字冲突的矛盾.

    笔试题:C++中extern "C"声明的作用?

    可以在函数声明前面加入extern “C”,要求C++编译器不对该函数进行换名,便于C程序直接调用该函数.

    注:被extern "C"声明的函数无法重载

  2. 哑元参数

    1)定义

    定义函数时,只有类型而没有变量名形参成为哑元.

    void func(int/哑元/){

    }

    2)使用哑元场景

    –》在操作符重载,区分前后++、–

    –》为了兼容以前的旧代码

    算法库:void math_func(int a,int b){…}

    使用者:

    int main(void){

    math_func(10,20);

    math_func(30,40);

    }

    升级算法库:void math_func(int a,int/哑元/){…}

    使用者:

    int main(void){

    math_func(10,20);

    math_func(30,40);

    }

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

    1)定义

    可以为函数的部分参数或全部参数指定缺省值,调用该函数时,如果不给实参,就取缺省值作为默认实参。

    void func(int a,int b,int flag=0/缺省参数/){}

    2)靠右原则,如果函数的一个参数有缺省值,那么该参数右侧的所有参数都必须带有缺省值.

    3)如果函数的定义和声明分开,缺省参数应该是写在函数的声明部分,而定义部分不写。

    #include <iostream>
    using namespace std;
    //函数声明
    void func(int a,int b = 20,int c = 30);
    //void func(int i){}//歧义错误
    int main(void){
        func(11,22,33);//11 22 33
        func(11,22);//11 22 30
        func(11);//11 20 30
        return 0;
    }
    //函数定义
    void func(int a,int b/*=20*/,int c/*=30*/){
        cout << "a=" << a << ",b=" << b << ",c=" 
            << c << endl;
    }
               
  4. 内联函数(inline)

    1)定义

    使用inline关键字修饰的函数即为内联函数,编译器将会尝试进行内联优化,可以避免函数调用的开销,提高代码执行效率.

    inline void func(void){}//内联函数

    2)使用说明

    –》多次调用的,小而简单的函数适合内联

    –》调用次数极少或大而复杂的函数不适合内联

    –》递归函数不能内联优化

    –》虚函数不能内联优化

    注:内联函数只是一种建议而不是强制要求,能否进行内联优化是由编译器决定的,有些函数不加inline修饰也会默认处理为内联优化,而有些函数即便加了inline修饰也会被编译器忽略掉.

继续阅读