C программирование: void* - Почему не параметрический полиморфизм?
Почему неправильно говорить, что мы можем реализовать параметрический полиморфизм в C-программировании с помощью void*?
Профессор поднял вопрос и никогда не отвечал. Я считаю, что пустота * на самом деле является чем-то очень низким уровнем, который можно считать параметрическим полиморфизмом, но есть ли более веская причина для этого?
2 ответа
Принимая это определение параметрического полиморфизма:
механизм для явной или неявной замены переменных типа конкретными типами при необходимости.
void *
не подходит.
C может сделать это с помощью макросов: http://rosettacode.org/wiki/Parametric_polymorphism
Возможно, потому что механизм "слишком механический", настолько, что он перестает быть полезным в том смысле, что полиморфизм должен быть полезным.
Кроме того, поскольку нет простого способа расширить полиморфную функцию после факта.
В C++ вы можете сделать это тривиально:
Matrix4x4 a, b, c;
a = ...; /* Initialize matrices. */
b = ...;
c = a + b; /* Use overloaded (polymorphic) operator + to add. */
В C++ выше используется operator+()
определены в Matrix4x4
класс, и может определить это при компиляции. Таким образом, при добавлении нового типа данных добавляется соответствующий код, описывающий, как сделать добавление, повторно используя существующий +
название. В Си вы не можете этого сделать.
в C, даже если у вас была функция
void super_add(void *sum, const void *a, const void *b);
как вы говорите об этом Matrix
, если вы только что написали тип? Вы должны иметь некоторую общую систему описания типов:
void super_add(const char *sum_type, void *sum, const char *atype, void *a, const char *btype, const void *b);
которому вы должны будете предоставить некоторую форму механизма регистрации, чтобы вы могли добавлять новые функции:
void super_add_register(const char *sum_type, const char *atype, const char *btype, void (*adder)(void *sum, const void *a, const void *b));
тогда вам нужно будет реализовать код, чтобы сопоставить имена типов с правильной функцией добавления, и так далее.
Короче говоря, оно того не стоит. Обратите внимание, однако, что есть библиотеки, которые делают это, например, GObject.