这取决于您要拥有的确切“面向对象”功能集。如果您需要重载和/或虚拟方法之类的东西,则可能需要在结构中包括函数指针:
typedef struct {
float (*computeArea)(const ShapeClass *shape);
} ShapeClass;
float shape_computeArea(const ShapeClass *shape)
{
return shape->computeArea(shape);
}
这将允许您通过“继承”基类并实现合适的功能来实现一个类:
typedef struct {
ShapeClass shape;
float width, height;
} RectangleClass;
static float rectangle_computeArea(const ShapeClass *shape)
{
const RectangleClass *rect = (const RectangleClass *) shape;
return rect->width * rect->height;
}
当然,这还需要您实现一个构造函数,以确保正确设置了函数指针。通常,您会为实例动态分配内存,但是您也可以让调用者这样做:
void rectangle_new(RectangleClass *rect)
{
rect->width = rect->height = 0.f;
rect->shape.computeArea = rectangle_computeArea;
}
如果要使用多个不同的构造函数,则必须“修饰”函数名称,不能有多个rectangle_new()
函数:
void rectangle_new_with_lengths(RectangleClass *rect, float width, float height)
{
rectangle_new(rect);
rect->width = width;
rect->height = height;
}
这是一个显示用法的基本示例:
int main(void)
{
RectangleClass r1;
rectangle_new_with_lengths(&r1, 4.f, 5.f);
printf("rectangle r1's area is %f units square\n", shape_computeArea(&r1));
return 0;
}
我希望至少能给您一些想法。对于一个成功且丰富的C面向对象框架,请查看glib的GObject库。
还要注意,上面没有建模任何显式的“类”,每个对象都有其自己的方法指针,这比您在C ++中通常找到的要灵活一些。另外,它会占用内存。您可以通过将方法指针填充到class
结构中来避免这种情况,并为每个对象实例发明一种引用类的方法。