zoukankan      html  css  js  c++  java
  • 第9课 函数重载分析(下)

    1. 函数重载函数指针

    (1)将重载函数名赋值给函数指针

    ①根据重载规则挑选与函数指针参数列表一致候选者

    严格匹配候选者函数类型与函数指针函数类型(所谓严格匹配,即函数参数及返回值都匹配

         

    【编程实验】函数重载 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 c = 0;
    
     
    
        PFUNC p = func; //编译器将根据函数指针的类型去严格匹配对应的函数
    
                        //所以会找到int func(int);其他函数则匹配不成功
    
     
    
        c = p(1); //
    
     
    
        printf("c = %d
    ", c); //1
    
     
    
        return 0;  
    
    }

    运行结果:

      

    (2)注意事项

      ①函数重载必然发生在同一个作用域中(如,同一个类或同一命名空间中)

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

      ③无法直接通过函数名得到重载函数入口地址(因为编译结束后,C++会根据重载函数命名的规则重命名各个函数,而原来的函数名实际上是找不到的)

    2. C++和C相互调用

    (1)实际工作中C++C代码相互调用不可避免的

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

    (3)C++编译器优先使用C++编译的方式

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

          

    【编程实验】C++调用C函数  9-2

    //add.h

    int add(int a, int b);

    //add.c

    #include "add.h"
    
     
    
    //该文件的编译,得到目标文件add.o
    
    //gcc -c add.c
    
    int add(int a, int b)
    
    {
    
        return a + b;
    
    }

    //main.cpp

    #include <stdio.h>
    
     
    
    //该文件的编译
    
    //g++ main.cpp add.o
    
     
    
    #ifdef __cplusplus
    
    extern "C" {
    
    #endif
    
     
    
    //C++中以C的方式编译:将add的函数名就是目标名
    
    #include "add.h"
    
     
    
    #ifdef __cplusplus
    
    }
    
    #endif
    
     
    
    int main()
    
    {
    
        int c = add(1, 2);
    
     
    
        printf("c = %d
    ", c); //3
    
     
    
        return 0;  
    
    }

    运行结果:

      

    3. 让C/C++代码只会以C的方式编译

    (1)C++内置的标准宏__cplusplus,可以确保C代码以统一的C方式编译

    #ifdef __cplusplus
    
    extern "C" {
    
    #endif
    
     
    
    ......; //C/C++代码,将以C的方式编译
    
     
    
    #ifdef __cplusplus
    
    }
    
    #endif

    【编程实验】C调用C++函数(其中的C++函数己经被按C方式编译

    //add.h

    //该文件的编译,得到目标文件add.o
    
    //g++ -c add.c
    
     
    
    #ifdef __cplusplus
    
    extern "C" {
    
    #endif
    
     
    
    //C++中以C的方式编译:add的函数名就是目标名
    
    int add(int a, int b);
    
     
    
    #ifdef __cplusplus
    
    }
    
    #endif

    //add.cpp

    #include "add.h"
    
     
    
    //该文件的编译,得到目标文件add.o
    
    //g++ -c add.c
    
     
    
    #ifdef __cplusplus
    
    extern "C" {
    
    #endif
    
     
    
    //C++中以C的方式编译:add的函数名就是目标名
    
    int add(int a, int b)
    
    {
    
        return a + b;
    
    }
    
     
    
    #ifdef __cplusplus
    
    }
    
    #endif

    //main.c

    #include <stdio.h>
    
    #include "add.h"
    
      //编译方式:
      //gcc main.c add.o
    
    int main()
    
    {
    
        int c = add(1, 2);
    
     
    
        printf("c = %d
    ", c); //3
    
     
    
        return 0;  
    
    }

    【编程实验】C调用C++函数其中的C++函数是C++方式编译

    ①假设别人提供了编译好的cpp的头文件和.o目标文件,但其中的函数是以C++方式编译的,很明显函数名是用C++方式命名的。我们的C文件里不方便使用这个的函数名。

    ②解决的方案是:做一个C++的封装层,对其中的函数进行一个封装,然后再用extern  "c"编译这些封装层中的函数,最后就可以在C文件中使用

    其他人编写的C++代码,其中的函数名是用C++方式编译的,但只提供的.h.o文件

    //add.h

    int add(int a, int b);

    //add.cpp

    #include "add.h"
    
     
    
    //编译命令:g++ -c add.cpp
    
     
    
    int add(int a, int b)
    
    {
    
        return a + b;
    
    }

    ▲我们的封装层

    //addEx.h

    int addEx(int a, int b);

    //addEx.cpp

    #include "add.h"
    
     
    
    //编译命令:
    
    //g++ -c addEx.cpp
    
     
    
    extern "C" int addEx(int a,int b)
    
    {
    
        return add(a, b);
    
    }

    ▲main.c演示的主文件

    #include <stdio.h>
    
    #include "addEx.h"
    
    //编译命令:
    
    //gcc main.c addEx.0 add.o
    
     
    
    int main()
    {
    
        int c = addEx(1, 2);
    
     
    
        printf("c = %d
    ", c); //3
    
     
    
        return 0;  
    
    }
    
     

    (2)注意事项

      ①C++编译器不能以C的方式编译重载函数,即如果在extern  "C"块里有两个同名的函数里,则会编译失败。

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

      • C++编译方式函数名参数列表编译成目标名

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

    4. 小结

    (1)函数重载C++对C一个重要升级

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

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

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

  • 相关阅读:
    又见博弈
    两道来自CF的题
    温习及回顾
    笔试面试总结
    Python Cha4
    初学ObjectiveC
    设计模式汇总(三)
    转贴XML的写法建议
    让从Objec中继承的类也拥有鼠标事件
    关于异常处理的一些看法
  • 原文地址:https://www.cnblogs.com/hoiday/p/10089126.html
Copyright © 2011-2022 走看看