gcc (GCC) 4.7.2
c89
我正在练习在 C 中使用一些面向对象的风格。因为我想为我们的一些较大的项目这样做。
但是,在下面的代码中,我有一个父结构汽车和一个子 sports_cars。但是,所有常见属性或汽车结构都将出现在子结构中。
我有一个问题,那就是 init 和 destory 函数。由于它们很常见,我希望我的子结构继承 init 和 destroy。但我认为我做错了。
car->init = init_car;
因为我有指向 init_car 的 init 函数指针,所以对我来说看起来不正确。
非常感谢您的建议,
#include <stdio.h>
#include <stdlib.h>
typedef struct tag_car car_t;
struct tag_car {
size_t wheels;
char *name;
void (*init)(void *self);
void (*destroy)(void *self);
size_t (*wheels_get)(void *self);
void (*wheels_set)(void *self, size_t num_wheels);
};
typedef struct tag_sports sports_t;
struct tag_sports {
car_t base_car;
size_t top_speed;
size_t (*top_speed_get)(void *self);
void (*top_speed_set)(void *self, size_t max_top_speed);
};
void destroy_car(void *self)
{
car_t *car = self;
free(car);
}
void init_car(void *self)
{
car_t *car = car;
car->wheels = 4;
car->name = NULL;
car->init = init_car;
car->destroy = destroy_car;
}
size_t wheels_count_get(void *self)
{
car_t *car = self;
return car->wheels;
}
void wheels_count_set(void *self, size_t num_wheels)
{
car_t *car = self;
car->wheels = num_wheels;
}
size_t sports_top_speed_get(void *self)
{
sports_t *sports_car = self;
return sports_car->top_speed;
}
void sports_top_speed_set(void *self, size_t max_top_speed)
{
sports_t *sports_car = self;
sports_car->top_speed = max_top_speed;
}
sports_t* init_sports()
{
sports_t *sports_car = malloc(sizeof(sports_t));
/* Parent struct */
sports_car->base_car.init = init_car;
sports_car->base_car.destroy = destroy_car;
sports_car->base_car.wheels_get = wheels_count_get;
sports_car->base_car.wheels_set = wheels_count_set;
/* Child struct */
sports_car->top_speed_set = sports_top_speed_set;
sports_car->top_speed_get = sports_top_speed_get;
return sports_car;
}
int main(void)
{
sports_t *farreri = init_sports();
sports_t *lamborghini = init_sports();
farreri->base_car.wheels_set(farreri, 10);
farreri->top_speed_set(farreri, 240);
printf("farreri has wheel count [ %ld ]\n", farreri->base_car.wheels_get(farreri));
printf("Farreri has a top speed [ %ld ]\n", farreri->top_speed_get(farreri));
lamborghini->base_car.wheels_set(lamborghini, 6);
lamborghini->top_speed_set(lamborghini, 220);
printf("lamborghini has wheel count [ %ld ]\n", lamborghini->base_car.wheels_get(lamborghini));
printf("Lamborghini has a top speed [ %ld ]\n", lamborghini->top_speed_get(lamborghini));
farreri->base_car.destroy(farreri);
lamborghini->base_car.destroy(lamborghini);
return 0;
}
最佳答案
在你的init_car
行
car->init = init_car;
car->destroy = destroy_car;
不应出现。您将构造行为与初始化混合在一起。在 C++ 中,构造函数负责完成这两件事;如果你想模拟相同的行为,你应该公开分配接口(interface)(例如,称之为construct
),它将分配内存(你的malloc
)并设置对象“方法” "到适当的函数)和初始化接口(interface)(它将执行初始化操作:car->wheels = 4; car->name = NULL;
)。分配方法可以调用初始化方法来实现C++行为。你会得到这样的结果:
void init_car(void *self)
{
car_t *car = self;
car->wheels = 4;
car->name = NULL;
}
sports_t* construct()
{
sports_t *sports_car = malloc(sizeof(sports_t));
/* Set the methods */
sports_car->base_car.init = init_car;
sports_car->base_car.destroy = destroy_car;
sports_car->base_car.wheels_get = wheels_count_get;
sports_car->base_car.wheels_set = wheels_count_set;
/* initialize the object */
sports_car->base_car.init();
return sports_car;
}
int main(void)
{
/* construct and init the objects */
sports_t *ferrari = construct();
sports_t *lamborghini = construct();
/* do your manipulations */
/* destroy the objects */
ferrari->base_car.destroy(farreri);
lamborghini->base_car.destroy(lamborghini);
return 0;
}
如果您不希望构造初始化对象,只需不要从 construct
调用初始化,而是在构造后通过调用 sports_car->base_car.init< 来调用它
.
关于c - 在C语言编程中使用oop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13511847/