龙空技术网

C语言如何支持C++重载?

海漂活化石 1075

前言:

现时咱们对“c语言有多个重载函数实例与参数列表匹配”大概比较珍视,姐妹们都需要分析一些“c语言有多个重载函数实例与参数列表匹配”的相关文章。那么小编在网上汇集了一些对于“c语言有多个重载函数实例与参数列表匹配””的相关资讯,希望同学们能喜欢,你们快快来学习一下吧!

C++重载有两种场景:

函数重载运算符重载

现在就两个场景分别给出答案。

如何用C语言实现C++函数重载?

根据笔者的经验,共有3种方法可以实现:

用C语言实现一个C++编译器的对应子集, 后者自然可以支持重载;用函数指针加上void指针类型参数强制类型转换,可以实现函数重载;用宏加上可变参数,可以实现函数重载如何用C语言实现C++运算符重载?

运算符在C语言中是保留字, 无法通过普通变通方法实现重载。只能用C语言实现一个C++编译器的对应子集, 后者自然可以支持重载。

用函数指针加上void指针类型参数强制类型转换,实现函数重载

用一个例子来说明:

typedef void (*funcOverride)(void *param);  void runFuncOverride(funcOverride f, void *param) {  f(param);}void func_with_int_param(void *iParam) {  int i = *(int *)iParam;  printf("int_param function is called, param is %d\n", i);}void func_with_char_param(void *cParam) {  char c = *(char *)cParam;  printf("char_param function is called, param is %c\n", c);}int i = 1;char c='2';runFuncOverride(func_with_int_param, &i);runFuncOverride(func_with_char_param, &c);

输出结果为:

bint_param function is called, param is 1char_param function is called, param is 2

这种方法有一个明显的劣势:

需要调用方事先指定函数指针挂接的实际调用的函数实体,即便是用变通的方式——将类型信息通过枚举类型或者字符串类型作为参数传递,也无法完美消除这个劣势。

根因是:运行时类型判断并未收纳于C语言标准规范中。

当然,一些C语言编译器可能会提供内置函数来实现该特性,但毕竟不是标准,无法满足跨平台的需求。比方说gcc就提供了__builtin_types_compatible_p和typeof这两个内置函数来做运行时类型判断。

用宏加上可变参数,实现函数重载

C语言支持可变参数,比方说prinf函数的原型如下:

int printf(const char *format, ...);

省略号表示参数为可变参数,而且C语言规定:省略号只能出现在函数形参的末尾,而且左边必须有普通的形参。

需要注意的是:对于宏没有上述限制。

C语言定义了一系列宏来完成可变参数函数参数的读取和使用:宏va_start、va_arg和va_end。

在ANSI C标准下,这些宏定义在stdarg.h中:

void va_start(va_list ap, last);//取第一个可变参数;type va_arg(va_list ap, type);//获取当前位置参数值void va_end(va_list ap);//将ap置为NULL

除此之外,还提供了一个非常有用的宏:__VA_ARGS__

这个宏直接引用可变参数列表。

有了上述前置知识,下面用一个例子来说明如何实现函数重载:

#define OneArgument(a) printf("One Argument func is called!\n")#define TwoArguments(a, b) printf("Two Arguments func is called!\n")#define MacroKernel(_1, _2, FUNC, ...) FUNC#define Macro(...) MacroKernel(__VA_ARGS__, TwoArguments, OneArgument, ...)(__VA_ARGS__)Macro(1);Macro(2,3);

输出结果为:

One Argument func is called!Two Arguments func is called!

上述代码估计有些小伙伴看了有点晕,现在做要点说明:

Macro宏定义展开其实是:调用MacroKernel宏展开的函数实体,调用参数为可变参数,由Macro宏括号中的内容定义。__VA_ARGS__其实引用的就是Macro宏定义括号中的可变参数列表。MacroKernel宏定义中的_1,_2都是占位符,没有实际含义,作用是:保证在传给Macro不同数目参数时,使得FUNC指向对应的函数实体:Macro参数数目为1时,FUNC指向OneArgument函数;参数数目为2时,FUNC指向TwoArguments函数。

下面来看看实际的展开效果:

Macro(1)

=>MacroKernel(1, TwoArguments, OneArgument, ...)(1)

=>OneArgument(1)

Macro(2, 3)

=>MacroKernel(2, 3, TwoArguments, OneArgument, ...)(2, 3)

=>TwoArguments(2, 3)

标签: #c语言有多个重载函数实例与参数列表匹配