0

我目前在 C 中使用 OOP 技术,并且我使用了在其结构中具有父类实例的子类的已知习语,如下所示:

struct parent{
    void (*doSomething)(struct parent *parent);
};

struct child{
    struct parent base;
    int (*doSomethingCooler)(struct child *child);
};

现在,我的方法以它们所属的类为前缀:

void parent_doSomething(struct parent *parent);
int child_doSomethingCooler(struct child *child);

随着重载,我有

void child_doSomethingCool(struct parent *parent);

我在子构造函数上设置为 parent->doSomething。

无论如何,当我有一个子实例并且我想调用父方法时,就会出现问题。立即,我必须将我的实例指针强制转换(C 中的 dynamic_cast 类型)到父类类型,这很快污染了我的代码。

第二个想法是定义所有方法来接收 void * "this" 参数,并在内部将它们转换为正确的类。这简化了客户端代码的使用,但将代码暴露给令人讨厌的错误,例如传递无效引用或错误类型的引用。

每种实施方式的优缺点是什么?

4

2 回答 2

3

使用 C11 的新类型通用特性,您可以统一访问父部件:

#define getParent(X)        \
_Generic((X),               \
    parent*: (X),           \
    child*: (&(X)->base)))

然后你可以用宏重载你的函数名

#define doSomething(X) doSomething(getParent(X))

正如您从这些示例中看到的那样,这对于通过指针调用“方法”的 OO 表示法不太适用,例如p->doSomething(),但这可能是一个开始。

于 2012-08-27T19:18:43.200 回答
0

我想到的一个解决方案是为每个类添加一个 MAGIC WORD,并在运行时检查它们。我可以通过保护这个“特性”避免在发布版本上编译来避免内存浪费和处理开销。

通过这种方式,我可以使用这些类简化客户端代码,并保护自己免受不良代码的影响。

于 2012-08-27T18:32:01.503 回答