首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在C中实现一个类?

如何在C中实现一个类?
EN

Stack Overflow用户
提问于 2009-09-10 07:47:29
回答 16查看 210.6K关注 0票数 159

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

限制:

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

回答 16

Stack Overflow用户

回答已采纳

发布于 2009-09-10 07:55:57

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

代码语言:javascript
复制
typedef struct {
  float (*computeArea)(const ShapeClass *shape);
} ShapeClass;

float shape_computeArea(const ShapeClass *shape)
{
  return shape->computeArea(shape);
}

这将允许您通过“继承”基类并实现适当的函数来实现一个类:

代码语言:javascript
复制
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;
}

当然,这也需要你实现一个构造函数,以确保函数指针被正确设置。通常情况下,您会为实例动态分配内存,但您也可以让调用者这样做:

代码语言:javascript
复制
void rectangle_new(RectangleClass *rect)
{
  rect->width = rect->height = 0.f;
  rect->shape.computeArea = rectangle_computeArea;
}

如果你想要几个不同的构造函数,你将不得不“修饰”函数名,你不能有多个rectangle_new()函数:

代码语言:javascript
复制
void rectangle_new_with_lengths(RectangleClass *rect, float width, float height)
{
  rectangle_new(rect);
  rect->width = width;
  rect->height = height;
}

下面是一个基本的用法示例:

代码语言:javascript
复制
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结构中填充方法指针来避免这种情况,并发明一种方法让每个对象实例引用一个类。

票数 101
EN

Stack Overflow用户

发布于 2009-09-10 07:56:19

为了做家庭作业,我也做了一次。我遵循了这种方法:

  1. 在结构中定义数据成员。
  2. 定义将指向结构的指针作为第一个参数的函数成员。
  3. 在一个头中执行这些操作&一个c.头用于结构定义和函数声明,c用于implementations.

一个简单的例子是:

代码语言:javascript
复制
/// Queue.h
struct Queue
{
    /// members
}
typedef struct Queue Queue;

void push(Queue* q, int element);
void pop(Queue* q);
// etc.
/// 
票数 31
EN

Stack Overflow用户

发布于 2009-09-10 07:57:17

如果只想要一个类,可以使用一个对象数组作为“struct”数据,并将指向它们的指针传递给“成员”函数。您可以在声明struct _whatever之前使用typedef struct _whatever Whatever向客户端代码隐藏实现。这样的“对象”和C标准库的FILE对象没有区别。

如果您想要多个具有继承和虚函数的类,则通常将指向函数的指针作为结构的成员,或者将指向虚函数表的共享指针作为结构成员。GObject库同时使用了这种技巧和类型定义技巧,并且得到了广泛的使用。

网上也有一本关于这方面的技术的书- Object Oriented Programming with ANSI C

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1403890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档