Может ли кто-нибудь указать мне ссылку на то, как реализовать фабричный шаблон с использованием ANSI C? Если будет охвачено больше шаблонов, это будет просто бонусом. Сделать это на C ++ для меня тривиально, но поскольку C не имеет классов и полиморфизма, я не совсем уверен, как это сделать. Я думал о том, чтобы иметь «базовую» структуру со всеми распространенными типами данных, а затем использовать указатели void и определять все общие части структур в том же порядке, что и в базовой структуре вверху? Или нет гарантии, что они так же попадают в память?
Реализация фабричного шаблона с использованием ANSI C
Ответы (4)
В C есть указатели на функции и структуры. Таким образом, вы можете реализовать классы на C.
что-то вроде этого должно дать вам ключ к разгадке.
void class1_foo() {}
void class2_foo() {}
struct polyclass
{
void (*foo)();
};
polyclass make_class1() { polyclass result; result.foo = class1_foo; return result; }
Заводской шаблон также может быть реализован на C, предположим, что следующие операции определяются вашим интерфейсом:
typedef int (*operations_1) (void *data);
typedef int (*operations_2) (void *data);
typedef struct impl_ops_t
{
operations_1 op1;
operations_2 op2;
} impl_ops_t;
Итак, чтобы иметь возможность получить экземпляр реализации, реализующий такой интерфейс, вы должны определить структуру как с данными, так и с операциями, затем вы можете определить операцию создания, которая вернет вам эту структуру и, возможно, также операции уничтожения:
typedef struct ctx_t
{
void *data;
impl_ops_t *operations;
} ctx_t;
typedef ctx_t (*create_handle) (void);
typedef void (*destroy_handle) (ctx_t **ptr);
typedef struct factory_ops
{
create_handle create;
destroy_handle destroy;
} factory_ops;
Вы также должны определить функцию, которая предоставляет вам фабричные методы, возможно, у вас должен быть способ получить правильную реализацию в зависимости от ваших потребностей (возможно, это не простой параметр, как в примере ниже):
typedef enum IMPL_TYPE
{
IMPL_TYPE_1,
IMPL_TYPE_2
} IMPL_TYPE;
factory_ops* get_factory(int impl_type);
Таким образом, он будет использоваться как:
main (...)
{
factory_ops fact = get_factory(IMPL_TYPE_2);
// First thing will be calling the factory method of the selected implementation
// to get the context structure that carry both data ptr and functions pointer
ctx_t *c = fact->create();
// So now you can call the op1 function
int a = c->operations->op1(c->data);
// Doing something with returned value if you like..
int b = c->operations->op2(c->data);
// Doing something with returned value if you like..
fact->destroy(&c);
return 0;
}
operations_1
и operations_2
напрямую? Есть ли польза от использования указателя на указатель на функцию?
- person Andy Lin; 10.01.2021
Шаблон Factory - это объектно-ориентированный шаблон проектирования.
C не является объектно-ориентированным языком.
Поэтому я бы спросил, какова ваша цель для Factory на C.