在C中进行OOP时模仿"this"指针的优美方法? [英] Elegant way to emulate 'this' pointer when doing OOP in C?

查看:103
本文介绍了在C中进行OOP时模仿"this"指针的优美方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to do some object-oriented style programming in C using polymorphism, where my interface class contains a pointer to a table of functions. Example something like:

/* 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;
}

我希望能够在不将s-> private显式传递到每个方法"中的情况下进行编写.有任何想法吗?也许有一些宏观技巧?

I'd like to be able to write something without explicitly passing s->private into every "method". Any ideas? Some macro tricks maybe?

推荐答案

如果这是公共接口的一部分,则可以添加访问器函数.一个隐藏的好处是您可以在访问器中执行完整性检查和其他工作. (请注意,我将"this"指针称为"o",就像在"object"中一样.为了保持一致性,我更喜欢这样.)

If this is part of the public interface, you can add accessor functions. A hidden benefit is that you can do sanity checks and other work in the accessor. (Note I called the "this" pointer "o", as in "object". I prefer it that way for consistency.)

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

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

    return ret;
}

您现在可以在不显式传递"private"的情况下调用它.

You can now call this without the explicit passing of "private".

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

    if (statement_analyse(s, foo))
        blah blah;
}

虽然这似乎没有任何好处,但是由于您仍然必须实现访问器,并假设需要一个定义良好且健壮的接口,所以访问器函数是放置断言和接口文档的唯一明智的选择.实际上,如果您编写好的断言,则断言本身可以帮助记录接口.并且,一旦在访问器中添加了健全性检查,就不必在它们调用的实际方法中添加它们.

While it may seem that this provides no benefit, because you still have to implement the accessors, assuming that you want a well defined and robust interface, the accessor functions are the only sane place to put the assertions and the interface documentation. In fact, if you write good assertions, the assertions themselves help document the interface. And once you add sanity checks in the accessors, you don't have to add them in the actual methods they call.

当然,只有通过函数指针调用的函数是用户提供的东西,或者以其他方式实现的东西不同时,这种方法才有意义.如果只有一个analyse()方法始终可以执行相同的操作,则可以简单地实现直接执行其所需操作的statement_analyse().

Of course, this approach only makes sense when the function called via the function pointer will be something provided by the user, or in some other way can be different things. If there's a single analyse() method that will always do the same thing, you can simply implement a statement_analyse() that directly does what it needs to do.

小注释:在进行OOP时,我更喜欢对这些结构进行typedef命名,并为其命名为CamelCase.我使用此约定作为一种方法来告诉该结构是不透明的,并且只能通过其公共接口进行访问.它看起来也更好,尽管那是主观的.我也更喜欢让用户为结构本身分配内存,而不是构造函数对其进行分配.这样可以避免必须处理malloc失败,并使程序更有效率.

Small note: when doing OOP, I prefer to typedef the structs and give them CamelCase names. I use this convention as a way of telling that the struct is opaque and should only be accessed via its public interface. It also looks nicer, though that is subjective. I also prefer having the user allocate the memory for the struct itself, as opposed to the constructor malloc'ing it. That avoids having to handle malloc failure, and makes the program a little bit more efficient.

typedef struct {
    ...
} Statement;

void Statement_Init (Statement *o);
int Statement_Analyse (Statement *o, int pc);

这篇关于在C中进行OOP时模仿"this"指针的优美方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆