【问题标题】:Is it possible to emulate object methods in C?是否可以在 C 中模拟对象方法?
【发布时间】:2012-02-14 14:45:00
【问题描述】:

是否可以在 C 中模拟对象方法?我希望能够自引用一个结构作为成员函数参数的参数,例如:

struct foo {
    int a;
    int (*save)(struct foo *);
};

int
save_foo(struct foo *bar) {
    // do stuff.
}

struct foo *
create_foo() {
    struct foo *bar = malloc(sizeof(struct foo));
    bar->save = save_foo;

    return bar;
}

int
main() {
    struct foo *bar = create_foo();

    bar->a = 10;
    bar->save();
}

bar->save(),实际上调用了save_foo(bar)。看起来很长,但它会很漂亮:)

【问题讨论】:

  • 好吧,因为所有其他语言都模拟对象方法,并且它们中的大多数至少部分在 C 中实现......(这将很有帮助:www.planetpdf.com/codecuts/pdfs/ooc。 pdf)
  • 如果你想要 C++,为什么不直接使用 C++ 编译器?
  • @BoPersson - 因为他试图实现的 OO 不是 C++ 的对象模型?

标签: c oop object emulation self-reference


【解决方案1】:

是的,这很尴尬。我在 Fortran77 中使用命名的公共块实现了对象。

在 C 中,结构可能是要走的路。如果您不想传递结构,则可以将它们设为全局并以这种方式访问​​它们。无论您选择什么解决方法,都请好好评论!

有时必须使用 C 而没有可用的 C++、Objective C 等。我喜欢 Java 和 C# 用于 OO 编程,但有时你必须凑合。

【讨论】:

    【解决方案2】:

    不,这是不可能的。 C中有面向对象的库,但它们将“this”对象显式传递给“方法”,如

    bar->save(bar);
    

    有关这种风格的示例,请参阅 Berkeley DB C API,但如果您想用类似 C 的语言执行 OO,请考虑使用 C++ 或 Objective-C。

    【讨论】:

    • 可以int save(struct foo *obj) { obj->save(obj); },这简化了对save(bar)的调用——不是“正确的顺序”,但足够接近,没有重复。
    • @ChrisLutz:重复仍然存在,但现在包装在 save 函数中(以及所有其他“方法”的独立包装器中)。
    • #define M(object, method, ...) ((object)->method(object, __VA_ARGS__)) 怎么样?
    • @ChrisLutz:对宏参数object 进行两次评估,因此不可靠。
    • 虽然这是真的,但我通常不会用任何看起来像 (x++)->method 的 OO 语言编写代码。如果您清楚地记录其局限性,则没有什么是“不可靠的”。
    【解决方案3】:

    是的,将bar 传递给save 函数指针,您将拥有C++ 在幕后所做的事情(不可见地将this 作为方法的第一个参数传递)。您无法在 C 中自动传递this(又名bar)。

    【讨论】:

    • 这更接近于 Objective-C 在底层所做的——方法查找是在运行时通过函数指针解析的,而在 C++ 中它将在编译时解析,即 C++ 代码会更接近到save_foo(bar),没有函数指针间接。
    【解决方案4】:

    答案是“是”。

    证明最初的 C++ 编译器根本就不是编译器。他们只是将 C++ 代码翻译成 C 代码。 CFront 编译器就是这样做的。

    我从其他答案中看到我可能误解了您的问题。不,您在问题中编写的语法在 C 中不起作用。您需要编写自己的预处理器/翻译器类型来将调用从 bar->save() 转换为 foo_save(bar) 甚至 C3fooF4save(bar)

    【讨论】:

    • 问题不在于使用 OOP 范式(可以用任何语言完成,尽管不应该这样做)。问题是关于一个特定的句法结构,据我所知,如果没有一个定制的(和一个非常聪明的)预处理器,这是不可能的。就像,是的,CFront。
    【解决方案5】:

    基本上没有。在 C 中对函数的引用只是一个指向它所在位置的指针,当你调用它时,你只是从结构中获取指针,跳转到那里并继续执行,而不需要任何关于上下文或堆栈的知识,所以有无处可取“这个”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-22
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多