zoukankan      html  css  js  c++  java
  • C++学习笔记(八):函数重载、函数指针和函数对象

    函数重载

    函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。

    1. 试想如果没有函数重载机制,如在C中,你必须要这样去做:为这个print函数取不同的名字,如print_int、print_string。这里还只是两个的情况,如果是很多个的话,就需要为实现同一个功能的函数取很多个名字,如加入打印long型、char*、各种类型的数组等等。这样做很不友好!
    2. 类的构造函数跟类名相同,也就是说:构造函数都同名。如果没有函数重载机制,要想实例化不同的对象,那是相当的麻烦!
    3. 操作符重载,本质上就是函数重载,它大大丰富了已有操作符的含义,方便使用,如+可用于连接字符串等!

    两个重载函数必须在下列一个或两个方面有所区别:

    1. 函数有不同参数。
    2. 函数有不同参数类型。

    返回值不作为判断两个函数区别的标志。

    C++运算符重载的相关规定如下:

    1. 不能改变运算符的优先级;
    2. 不能改变运算符的结合型;
    3. 默认参数不能和重载的运算符一起使用;
    4. 不能改变运算符的操作数的个数;
    5. 不能创建新的运算符,只有已有运算符可以被重载;
    6. 运算符作用于C++内部提供的数据类型时,原来含义保持不变。

    总结示例:

    (1)普通函数(非类成员函数)形参完全相同,返回值不同,如:

    1 void print();
    2 int print(); //不算重载,直接报错

    (2)普通函数形参为非引用类型,非指针类型,形参一个带const,一个不带const

    1 void print(int x);
    2 void print(const int x); //不算重载,直接报错重定义

    (3)普通函数形参为引用类型或指针类型,一个形参带const,一个不带const

    1 void print(int *x);
    2 void print(const int *x); //算重载,执行正确,实参为const int *时候调用这个,为int* 的时候调用上面一个
    3 
    4 void print(int &x);
    5 void print(const int &x); //算重载,执行正确,实参为const int &时候调用这个,为int& 的时候调用上面一个

    (4)类的成员函数,形参完全相同,一个函数为const成员函数,一个函数为普通成员函数

    1 void print();
    2 void print() const; //算重载。const对象或const引用const指针调用时调用这个函数,普通对象或普通引用调用时调用上面一个。

    函数指针

    函数指针(或称为回调函数)是一个很有用也很重要的概念。当发生某种事件时,其它函数将会调用指定的函数指针指向的函数来处理特定的事件。

    注意:定义的一个函数指针是一个变量。

    定义一个函数指针:

    两种格式:

    1. 返回类型 (*函数指针名称)(参数类型,参数类型,参数类型,…);
    2. 返回类型 (类名称::*函数成员名称)(参数类型,参数类型,参数类型,….)

    示例:

    1 int (*pFunction)(float,char,char)=NULL;//C语言的函数指针
    2 int (MyClass::*pMemberFunction)(float,char,char)=NULL;//C++的函数指针,非静态函数成员
    3 int (MyClass::*pConstMemberFunction)(float,char,char) const=NULL;//C++的函数指针,静态函数成员

    C函数指针赋值和调用:

    赋值:

    1 int func1(float f,int a,int b){return f*a/b;}
    2 int func2(float f,int a,int b){return f*a*b;}
    3 //然后我们给函数指针pFunction赋值
    4 pFunction=func1;
    5 pFunction=&func2;

    上面这段代码说明了两个问题:

    1. 一个函数指针可以多次赋值。
    2. 取地址符号是可选的,却是推荐使用的。

    调用:

    1 pFunction(10.0,’a’,’b’);
    2 (*pFunction)(10.0,’a’,’b’);

    C++类里的函数指针赋值和调用:

    定义类:

     1 MyClass
     2 {
     3 public:
     4     int func1(float f,char a,char b)
     5     {
     6         return f*a*b;
     7     }
     8     int func2(float f,char a,char b) const
     9     {
    10         return f*a/b;
    11     }
    12 }

    赋值:

    1 MyClass mc;
    2 pMemberFunction= &mc.func1;//必须要加取地址符号
    3 pConstMemberFunction = &mc.func2;

    调用:

    1 (mc.*pMemberFunction)(10.0,’a’,’b’);
    2 (mc.*pConstMemberFunction)(10.0,’a’,’b’);

    函数指针作为参数:

     1 #include<stdio.h> 
     2  
     3 float add(float a,float b){return a+b;} 
     4  
     5 float minus(float a,float b){return a-b;} 
     6  
     7 float multiply(float a,float b){return a*b;} 
     8  
     9 float divide(float a,float b){return a/b;} 
    10  
    11 int pass_func_pointer(float (*pFunction)(float a,float b)) 
    12 { 
    13       float result=pFunction(10.0,12.0); 
    14       printf("result=%f
    ",result); 
    15 } 
    16  
    17 int main() 
    18 { 
    19       pass_func_pointer(add); 
    20       pass_func_pointer(minus); 
    21       pass_func_pointer(multiply); 
    22       pass_func_pointer(divide); 
    23       return 0; 
    24 } 

    使用函数指针作为返回值:

    对于以下形式:

    1 float (* func(char op) ) (float ,float)

    其具体含义就是,声明了这样一个函数:

    1. 其名称为func,其参数的个数为1个;
    2. 其各个参数的类型为:op—char;
    3. 其返回变量(函数指针)类型为:float(*)(float,float)

    示例:

     1 #include<stdio.h> 
     2  
     3 #include<stdlib.h> 
     4  
     5 #include<string.h> 
     6  
     7 float add(float a,float b){return a+b;} 
     8  
     9 float minus(float a,float b){return a-b;} 
    10  
    11 float multiply(float a,float b){return a*b;} 
    12  
    13 float divide(float a,float b){return a/b;} 
    14  
    15   
    16  
    17 float(* FunctionMap(char op) )(float,float) 
    18  
    19 { 
    20  
    21       switch(op) 
    22  
    23       { 
    24  
    25              case '+': 
    26  
    27                     return add; 
    28  
    29                     break; 
    30  
    31              case '-': 
    32  
    33                     return minus; 
    34  
    35                     break; 
    36  
    37              case '*': 
    38  
    39                     return multiply; 
    40  
    41                     break; 
    42  
    43              case '\': 
    44  
    45                     return divide; 
    46  
    47                     break; 
    48  
    49              default: 
    50  
    51                     exit(1); 
    52  
    53       } 
    54  
    55 } 
    56  
    57   
    58  
    59 int main() 
    60  
    61 { 
    62  
    63       float a=10,b=5; 
    64  
    65       char ops[]={'+','-','*','\'}; 
    66  
    67       int len=strlen(ops); 
    68  
    69       int i=0; 
    70  
    71       float (*returned_function_pointer)(float,float); 
    72  
    73       for(i=0;i<len;i++) 
    74  
    75       { 
    76  
    77              returned_function_pointer=FunctionMap(ops[i]); 
    78  
    79              printf("the result caculated by the operator %c is %f
    ",ops[i],returned_function_pointer(a,b)); 
    80  
    81       } 
    82  
    83       return 0; 
    84  
    85 } 

    使用函数指针数组:

    定义一个指向函数指针类型为:float (*)(float,float)的函数指针数组,数组长度为10.正确的形式为:

    1 float(* pFunctionArray[10])(float,float)

    示例:

     1 #include<stdio.h> 
     2  
     3 float add(float a,float b){return a+b;} 
     4  
     5 float minus(float a,float b){return a-b;} 
     6  
     7 float multiply(float a,float b){return a*b;} 
     8  
     9 float divide(float a,float b){return a/b;} 
    10  
    11 int main() 
    12  
    13 { 
    14       float(*func_pointers[4])(float,float)={add,minus,multiply,divide}; 
    15       int i=0; 
    16       float a=10.0,b=5.0; 
    17  
    18       for(i=0;i<4;i++) 
    19       { 
    20              printf("result is %f
    ",func_pointers[i](a,b)); 
    21       } 
    22       return 0; 
    23 } 

    使用typedef进行简化:

    typedef一般使用形式如下:

    1 typedef int bool;

    这在C语言中很常用,由于C语言中没有bool类型,这样定义之后可以从形式上引入一个bool类型,提高代码可读性。

    然而在使用typedef定义函数指针类型的时候,和普通的使用typedef引入新类型的方式不一样。

    在我们要将float (*)(float,float)类型声明为一种新类型,应该是:

    1 typedef float(*fpType)(float,float);

    这样我们就可以用fpType来表示float (*)(float,float)这种类型了,使用如下:

     1 fpType pFunction;
     2 
     3 //在定义函数指针数组的时候可以这样定义:
     4 fpType pFunctions[10];
     5 
     6 //在定义函数指针类型参数时可以这样定义:
     7 void func(fpType pFunction);
     8 
     9 //在定义函数指针类型的返回值时可以这样定义:
    10 fpType func(int a);

    函数对象

    函数对象实质上是一个实现了operator()括号操作符的类。

     1 class Add  
     2 {  
     3 public:  
     4 int operator()(int a, int b)  
     5 {  
     6 return a + b;  
     7 }  
     8 };  
     9 Add add; // 定义函数对象  
    10 cout << add(3,2); // 5 

    函数指针版本是:

    1 int AddFunc(int a, int b)  
    2 {  
    3 return a + b;  
    4 }  
    5 typedef int (*Add) (int a, int b);  
    6 Add add = &AddFunc;  
    7 cout << add(3,2); // 5 

    既然C++函数对象与函数指针在使用方式上没什么区别,那为什么要用函数对象呢?很简单,函数对象可以携带附加数据,而指针不行。

  • 相关阅读:
    express如何使用cors插件、body-parser插件
    如何让xshell关闭后依然运行node项目
    nuxt命令和部署
    Python—函数的名称空间
    Python—生成器
    Python—闭包
    Python入门-字符串常用方法
    Python入门-函数
    Python入门-文件操作
    Python入门-三级菜单
  • 原文地址:https://www.cnblogs.com/hammerc/p/4024015.html
Copyright © 2011-2022 走看看