我遇到了以下函数签名,我想知道这个(省略号,或者"...")是否是某种多态性?
#include <fcntl.h>
int fcntl(int fd, int cmd, ... );
Run Code Online (Sandbox Code Playgroud)
提前致谢.
rix*_*rrr 11
这...意味着您可以将任意数量的参数传递给此函数,正如其他评论者已经提到的那样.由于未键入可选参数,因此编译器无法检查类型,您可以在技术上传递任何类型的任何参数.
那么这是否意味着您可以使用它来实现某种多态函数?(即,基于其参数类型执行某些操作的函数.)
没有.
你不能这样做的原因是因为你不能在运行时检查传入的参数的类型.变量参数列表中的函数读取应该已经知道它将接收的可选参数的类型.
如果一个函数真的应该能够接受任何类型的任意数量的参数(即printf),那么参数的类型将通过格式字符串传递.这意味着调用者必须在每次调用时指定它将传递的类型,从而消除多态函数的好处(调用者也不必知道类型).
相比:
// Ideal invocation
x = multiply(number_a, number_b)
y = multiply(matrix_a, matrix_b)
// Standard C invocation
x = multiply_number(number_a, number_b)
y = multiply_matrix(matrix_a, matrix_b)
// Simulated "polymorphism" with varargs
x = multiply(T_NUMBER, number_a, number_b)
y = multiply(T_MATRIX, matrix_a, matrix_b)
Run Code Online (Sandbox Code Playgroud)
你必须在varargs函数做正确的事情之前指定类型,这样你什么也得不到.
不,那是你在那里看到的"省略号",假设你指...的是宣言的那一部分.
基本上它表示此函数在前两个参数之后接受未知数量的参数.
该函数必须以这样一种方式编写,即它知道会发生什么,否则会产生奇怪的结果.
对于支持此功能的其他功能,请查看printf函数及其变体.
C支持多态吗?不,它没有.
但是有几个库,比如Python C API,它使用结构和指针实现了多态的粗略变体.请注意,在大多数情况下,编译器无法执行适当的类型检查.
tecnhique很简单:
typedef struct {
char * (*to_string)();
} Type;
#define OBJ_HEADER Type *ob_type
typedef struct {
OBJ_HEADER;
} Object;
typedef struct {
OBJ_HEADER;
long ival;
} Integer;
typedef struct {
OBJ_HEADER;
char *name;
char *surname;
} Person;
Run Code Online (Sandbox Code Playgroud)
Integer和Person获得一个带有适当函数指针的Type对象(例如,对于integer_to_string和person_to_string等函数).
现在只声明一个接受Object*的函数:
void print(Object *obj) {
printf("%s", obj->type->to_string());
}
Run Code Online (Sandbox Code Playgroud)
现在你可以用Integer和Person调用这个函数:
Integer *i = make_int(10);
print((Object *) i);
Person *p = make_person("dfa");
print((Object *) p);
Run Code Online (Sandbox Code Playgroud)
编辑
或者你可以将i和p声明为Object*; 当然make_int和make_person将为Integer和Person分配空间并进行适当的转换:
Object *
make_integer(long i) {
Integer *ob = malloc(sizeof(Integer));
ob->ob_type = &integer_type;
ob->ival = i;
return (Object *) ob;
}
Run Code Online (Sandbox Code Playgroud)
注意:我现在无法编译这些示例,请仔细检查它们.
我遇到了以下函数签名,我想知道这个(省略号,或"......")是否是某种多态性?
是的,它是多态的原始形式.只有一个功能签名,您可以传递各种结构.但是,编译器无法帮助您检测类型错误.