假设我必须使用C(没有C++或面向对象的编译器),并且我没有动态内存分配,那么我可以使用哪些技术来实现一个类,或者一个类的一个很好的近似值?将“类”隔离到一个单独的文件中总是一个好主意吗?假设我们可以通过假设固定数量的实例,或者甚至在编译前将对每个对象的引用定义为常量来预先分配内存。请随意假设我需要实现哪个OOP概念(可能会有所不同),并为每个概念提出最好的方法。
限制:
发布于 2009-09-10 07:55:57
这取决于你想要的确切的“面向对象的”特性集。如果你需要像重载和/或虚方法这样的东西,你可能需要在结构中包含函数指针:
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
结构中填充方法指针来避免这种情况,并发明一种方法让每个对象实例引用一个类。
发布于 2009-09-10 07:56:19
为了做家庭作业,我也做了一次。我遵循了这种方法:
一个简单的例子是:
/// Queue.h
struct Queue
{
/// members
}
typedef struct Queue Queue;
void push(Queue* q, int element);
void pop(Queue* q);
// etc.
///
发布于 2009-09-10 07:57:17
如果只想要一个类,可以使用一个对象数组作为“struct
”数据,并将指向它们的指针传递给“成员”函数。您可以在声明struct _whatever
之前使用typedef struct _whatever Whatever
向客户端代码隐藏实现。这样的“对象”和C标准库的FILE
对象没有区别。
如果您想要多个具有继承和虚函数的类,则通常将指向函数的指针作为结构的成员,或者将指向虚函数表的共享指针作为结构成员。GObject库同时使用了这种技巧和类型定义技巧,并且得到了广泛的使用。
网上也有一本关于这方面的技术的书- Object Oriented Programming with ANSI C。
https://stackoverflow.com/questions/1403890
复制相似问题