我看到了下面的函数签名,我想知道这个(省略号或者"..."
)是不是一种多态?
#include <fcntl.h>
int fcntl(int fd, int cmd, ... );
提前感谢。
我看到了下面的函数签名,我想知道这个(省略号或者"..."
)是不是一种多态?
#include <fcntl.h>
int fcntl(int fd, int cmd, ... );
提前感谢。
...
表示你可以向此函数传递任意数量的参数,正如其他评论者已经提到的。由于可选参数没有类型,编译器无法检查类型,因此你可以在技术上传递任何类型的任何参数。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)
在可变参数函数可以正确执行之前,您必须指定类型,因此这样做并没有任何好处。
...
部分。printf
函数及其变体。C语言支持多态吗? 不支持。
然而,有几个库,比如Python C API,使用结构体和指针实现了多态的粗略变体。请注意,大多数情况下编译器无法执行适当的类型检查。
这种技术很简单:
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;
整数和人员使用适当的函数指针(例如integer_to_string和person_to_string函数)获取类型对象。
现在只需声明一个接受Object *的函数:
void print(Object *obj) {
printf("%s", obj->type->to_string());
}
Integer *i = make_int(10);
print((Object *) i);
Person *p = make_person("dfa");
print((Object *) p);
编辑
或者您可以将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;
}
注意:我现在无法编译这些示例,请仔细检查。
我遇到了下面的函数签名,我想知道这个省略号(或“...”)是一种多态吗?
是的,它是一种原始形式的多态。只有一个函数签名,您就可以传递各种结构。但是编译器无法帮助您检测类型错误。
print
需要接受一个 void*
类型的参数,然后你需要显式地将它转换为 Object*
类型,以使你的示例正常工作。 - Konrad Rudolphqsort
函数,它可以对任意类型的数据进行排序。void
)指针来完成这个功能。同时,需要知道要排序的数据的大小(通过 sizeof
提供),以及比较对象顺序的逻辑。这通过向 qsort
函数传递函数指针来实现。DefWindowProc
),以模拟调用基类的虚方法。C语言支持一种简单的多态形式,即一种类型能够以另一种类型的方式出现和表现。它在底层上与C++类似(依赖于内存对齐),但您需要通过强制转换来帮助编译器。例如,您可以定义一个结构体:
typedef struct {
char forename[20];
char surname[20];
} Person;
然后是另一个结构体:
typedef struct {
char forename[20];
char surname[20];
float salary;
char managername[20];
} Employee;
那么
int main (int argc, int *argv)
{
Employee Ben;
setpersonname((Person *) &Ben);
}
void setpersonname(Person *person)
{
strcpy(person->forename,"Ben");
}
那不是技术上的多态性。fcntl接受可变数量的参数,这就是为什么它与printf函数类似的原因。