在C中进行OOP时,优雅的方式来模拟'this'指针?

blu*_*ift 1 c oop polymorphism

我想在C中使用多态进行一些面向对象的样式编程,其中我的接口类包含一个指向函数表的指针.例如:

/* Implement polymorphism in C, Linux kernel-style */
struct statement {
    const struct statement_ops *ops;
    struct list_head list;      /* when on master input list */
    void *private;          /* pointer to type-specific data */
};

struct statement_ops {
    int (*analyse)(void *private, int pc);
    int (*get_binary_size)(void *private);
};

void user(void)
{
    struct statement *s = make_a_statement();
    if (s->ops->analyse(s->private, foo))
        blah blah;
}
Run Code Online (Sandbox Code Playgroud)

我希望能够在没有明确地将s-> private传递给每个"方法"的情况下编写内容.有任何想法吗?一些宏观技巧可能吗?

Amb*_*jak 6

如果这是公共接口的一部分,则可以添加访问器功能.隐藏的好处是您可以在访问者中进行健全性检查和其他工作.(注意我将"this"指针称为"o",就像在"object"中一样.我更喜欢这种方式以保持一致性.)

int statement_analyse (struct statement *o, int pc)
{
    assert(pc >= 0);

    int ret = o->ops->analyse(o->private, pc);
    assert(ret >= 0);

    return ret;
}
Run Code Online (Sandbox Code Playgroud)

你现在可以在没有明确传递"私人"的情况下调用它.

void user(void)
{
    struct statement *s = make_a_statement();

    if (statement_analyse(s, foo))
        blah blah;
}
Run Code Online (Sandbox Code Playgroud)

虽然看起来这似乎没有任何好处,因为你仍然必须实现访问器,假设你需要一个定义良好且健壮的接口,访问器函数是放置断言和接口文档的唯一理智的地方.实际上,如果你编写好的断言,断言本身有助于记录接口.一旦在访问器中添加了健全性检查,就不必在他们调用的实际方法中添加它们.

当然,这种方法只有在通过函数指针调用的函数是用户提供的东西时才有意义,或者以某种其他方式可以是不同的东西.如果只有一种analyse()方法总能做同样的事情,你可以简单地实现一个statement_analyse()直接做它需要做的事情.

小注意:在进行OOP时,我更喜欢键入结构并给它们CamelCase名称.我使用这个约定来告诉结构是不透明的,只能通过它的公共接口访问.虽然这是主观的,但它看起来也更好.我也更喜欢让用户为结构本身分配内存,而不是构造函数malloc'ing它.这避免了必须处理malloc故障,并使程序更有效.

typedef struct {
    ...
} Statement;

void Statement_Init (Statement *o);
int Statement_Analyse (Statement *o, int pc);
Run Code Online (Sandbox Code Playgroud)