【C++】 9_函数重载分析 (下)

发布时间:2019-06-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【C++】 9_函数重载分析 (下)脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

重载与指针

  • 函数重载遇上函数指针

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

      • 根据重载规则挑选与函数指针参数列表一致的候选者
      • 严格匹配候选者的函数类型与函数指针的函数类型

编程实验: 函数重载 VS 函数指针

#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 c);

int main(int argc, char* argv[])
{
    int c = 0;
    
    PFUNC p = func;
    
    c = p(1);
    
    printf(@H_430_126@"c = %dn", c);

    return 0;
}
输出:
c = 1
  • 注意

    • 函数重载必然发生在同一个作用域
    • 编译器需要用参数列表函数类型进行函数选择
    • 无法直接通过函数名得到重载函数的入口

应该怎样获得某一个重载函数的地址呢?

#include <stdio.h>

int add(int a, int b)  // int(int, int)
{
    return a + b;
}

int add(int a, int b, int c) // int(int, int, int)
{
    return a + b + c;
}

int main()
{
    printf("%pn", (int(*)(int, int))add);        // 通过类型转换得到函数指针 
    printf("%pn", (int(*)(int, int, int))add);

    return 0;
}

C++ 和 C 相互调用

  • 实际工程中 C++ 和 C 代码相互调用是不可避免的(尤其在已经存在的C码或C库)
  • C++ 编译器能够兼容 C 语言的编译方式
  • C++ 编译器会优先使用 C++ 编译的方式
  • extern 关键字能强制让 C++ 编译器进行 C 方式的编译
extern "C"
{
    // do C-style compilation here
}

编程实验: C++ 调用 C 函数

add.h

int add(int a, int b);

add.c

#include "add.h"

int add(int a, int b)
{
    return a + b;
}

main_1.cpp

#include <stdio.h>
#include "add.h"

int main()
{
    int c = add(1, 2);
    
    printf("c = %dn", c);
    
    return 0;
}
gcc -c add.c -o add.oo
g++ add.h add.oo main.cpp 
 
输出:
main_1.cpp:(.text+0x19): undefined reference to `add(int, int)'
collect2: ld returned 1 exit status

main_2.c

#include <stdio.h>
extern "C"
{

#include "add.h"

}

int main()
{
    int c = add(1, 2);
    
    printf("c = %dn", c);
    
    return 0;
}
输出:
c = 3

分析:【不同的编译方式导致不同的编译结果】
gcc 编译 add.c add.h 生成 add.oo 中的符号表
00000000 T add

g++ 编译 add.c add.h 生成 add.oo 中的符号表
00000000 T _Z3addii
     U __gxx_personality_v0

问题: 如何保证一段 C 代码只会以 C 的方式被编译?

  • __cplusplus 是 C++ 编译器内置的标准宏定义
  • __cplusplus 的意义:确保 C 代码以统一的 C 方式被编译成目标文件
#ifdef __cpusplus
extern "C" {
#endif

// C-Style Compilation

#ifdef __cpluscplus
}
#endif

编程实验: C 调用 C++ 函数

add.h

int add(int a, int b);

add.c

#include "add.h"

int add(int a, int b)
{
    return a + b;
}

main.c

#include <stdio.h>

#ifdef __cplusplus
extern "C"
{
#endif

#include "add.h"

#ifdef __cplusplus
}
#endif

int main()
{
    int c = add(1, 2);
    
    printf("c = %dn", c);
    
    return 0;
}
输出:
c = 3

注意事项

  • C++ 编译器不能以 C 的方式编译重载函数
  • 编译方式决定函数名被编译后的目标名
  • C++ 编译方式将函数名和参数列表编译成目标名
  • C 编译方式只将函数名作为目标名进行编译

小结

  • 函数重载是 C++ 对 C 的一个重要升级
  • 函数重载通过函数参数列表区分不同的同名函数
  • extern 关键字能够实现 C 和 C++ 的相互调用
  • 编译方式决定符号表中的函数名的最终目标名

以上内容参考狄泰软件学院系列课程,请大家保护原创

脚本宝典总结

以上是脚本宝典为你收集整理的【C++】 9_函数重载分析 (下)全部内容,希望文章能够帮你解决【C++】 9_函数重载分析 (下)所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。