如何在C中实现类?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (9)

假设我必须使用C(没有C ++或面向对象的编译器),并且我没有动态内存分配,那么我可以使用一些技术来实现一个类,或者一个类的很好的近似值?将“班级”隔离到一个单独的文件中总是一个好主意吗?假定我们可以通过假定固定数量的实例来预先分配内存,或者甚至在编译时间之前将每个对象的引用定义为常量。随意对我将需要实现哪个OOP概念做出假设(它会有所不同),并为每个概念提供最佳方法。

限制:

  • 我必须使用C而不是OOP,因为我正在为嵌入式系统编写代码,并且编译器和预先存在的代码库位于C中。
  • 没有动态内存分配,因为我们没有足够的内存来合理地认为如果我们开始动态分配它,我们不会耗尽。
  • 我们使用的编译器在函数指针方面没有问题
提问于
用户回答回答于

这取决于想要的确切的“面向对象”功能集。如果你需要重载和/或虚拟方法之类的东西,你可能需要在结构中包含函数指针:

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结构中来避开这种情况,并为每个对象实例创建一个引用类的方法。

用户回答回答于

方法:

  1. 在结构中定义数据成员。
  2. 定义你的函数成员,它将一个指向你的结构的指针作为第一个参数。
  3. 在一个标题和一个c中执行这些操作。头结构定义和函数声明,C实现。

一个简单的例子就是:

/// Queue.h
struct Queue
{
    /// members
}
typedef struct Queue Queue;

void push(Queue* q, int element);
void pop(Queue* q);
// etc.
/// 

扫码关注云+社区