第9课 - 函数重载分析(下)

1、重载与指针 

       1)下面的函数指针将保存哪个函数的地址?


        函数重载遇上函数指针 

            -将重载函数名赋值给函数指针时 

                1. 根据重载规则挑选与函数指针参数列表—致的候选者 

                2. 严格匹配候选者的函数类型与函数指针的函数类型 


2、编程实验

函数垂载VS函数指针     9-1.cpp

#include <stdio.h>  
#include <string.h>  
  
int func(int x)  
{  
    return x;  
}  
  
int func(int a, int b)  
{  
    return a + b;  
}  
  
int func(const char* s)  
{  
    return strlen(s);  
}  
  
typedef int(*PFUNC)(int a);  
  
  
int main(int argc, char *argv[])  
{  
    int c = 0;  
  
    PFUNC p = func;  
          
    c = p(1);     
      
    printf("c = %d\n", c);  
  
    return 0;  
}  

                                    

                                        当修改:typedef void(*PFUNC)(int a);

                        

                                     可以通过函数指针类型获得重载函数的地址

                                                    如:int(*)(int,int,int)

            注意 

                -函数重载必然发生在同—个作用域中 

                -编译器需要用参数列表或函数类型进行函数选择 

                -无法直接通过函数名得到重载函数的入口地址

3、C++和C相互调用 

            实际工程中C++和C代码相互调用是不可避免的 

            C++编译器能够兼容C语言的编译方式 

            C++编译器会优先使用C++编译的方式 

            extern关键字能强制让C++编译器进行C方式的编译 

  1. extern "C"   
  2.          {   
  3.                  //do C-style compilation here   
  4.   
  5.          }   


4、编程实验

C++调用C函数     9-2 .cpp

add.h

  1. int add(int a, int b);  

add.c

  1. #include "add.h"  
  2.   
  3.   
  4.   
  5. int add(int a, int b)  
  6.   
  7. {  
  8.   
  9.     return a + b;  
  10.   
  11. }  


main.cpp

#include <stdio.h>  
    
extern "C" 
{  
#include "add.h"
}  
    
int main()  
{  
    int c = add(1, 2);  
      
    printf("c = %d\n", c);  
      
    return 0;  
} 


                

                

                加extern,用gcc将add.c生成.o文件,g++编译器可以

                成功编译main.cpp和add.o。而不加, g++编译器报错


5、问题

            如何保证—段C代码只会以C的方式披编译? 

                    如:用gcc编译上面代会出错


6、解决方案

        __cplusplus是C++编译器内置的标准宏定义 

        __cplusplus的意义 

                -确保C代码以统—的C方式被编译成目标文件

  1. #ifdef __cplusplus   
  2. extern "C"  
  3. {   
  4. #endif   
  5.   
  6.         //C-Style Compilation   
  7.           
  8. #ifdef __cplusplus   
  9. }  
  10. #endif   


main.cpp

#include <stdio.h>  
  
#ifdef __cplusplus  
extern "C" {  
#endif  
  
#include "add.h"  //这样设计才能保证这一头文件一直被正常调用
  
#ifdef __cplusplus  
}  
#endif  
  
  
int main()  
{  
    int c = add(1, 2);  
      
    printf("c = %d\n", c);  
      
    return 0;  
}  

                                


7、编程实验

            C调用C++函数 课后练习

            答:实现原理:  用一个函数将C++类的使用封装起来,

                    然后将它外部声明为C函数


8、注意事项

            C++编译器不能以C的方式编译重载函数

            编译方式决定函数名被编译后的目标名 

                    - C++编译方式将函数名和参数列表编译成目标名 

                    - C编译方式只将函数名作为目标名进行编译 


  1. #include <stdio.h>  
  2.   
  3. int add(int a, int b)  // int(int, int)  
  4. {  
  5.     return a + b;  
  6. }  
  7.   
  8. int add(int a, int b, int c) // int(int, int, int)  
  9. {  
  10.     return a + b + c;  
  11. }  
  12.   
  13. int main()  
  14. {  
  15.     printf("%p\n", (int(*)(intint))add);  
  16.     printf("%p\n", (int(*)(intintint))add);  
  17.   
  18.     return 0;  
  19. }  

                                

                                        nm命令用于显示二进制目标文件的符号表
                                        后面的就是被编译的目标函数名
                                        extern “C”间决不能出现重载函数

9、小结

            函数重载是C++对C的—个重要升级 

            函数重载通过函数参数列表区分不同的同名函数 

            extern关键字能够实现C和C++的相互调用 

            编译方式决定符号表中的函数名的最终目标名 

猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/79672883
今日推荐