5

GObjectクラスAはインターフェイスIAを実装し、BはAの派生クラスです。BはインターフェイスIAの一部であるAのメソッドをどのようにオーバーライドできますか?

または、これはGObjectで可能ですか?

親クラスのメソッドをオーバーライドする方法は知っていますが、継承がインターフェイスと出会うと、事態はより複雑になるようです。

どうもありがとう!

4

2 に答える 2

5

より良い解決策は、A が接続されているインターフェイスを B に再実装させるよりも、A のメソッドを仮想化することだと思います (これには、1 つの関数を再定義するだけでなく、より多くの作業が必要になる場合があります)。 fooable インターフェイス定義以外):

#include <glib-object.h>
#include "fooable.h"

typedef struct {GObject parent;} A;
typedef struct {
    GObjectClass parent;
    gint (*foo) (Fooable *self, gdouble quux);
} AClass;

#define TYPE_A           (a_get_type())
#define A_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST((cls), TYPE_A, AClass))
#define A_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), TYPE_A, AClass))

gint a_foo_real (Fooable *self, gdouble quux) {
    g_print("a_foo_real(%g)\n", quux);
    return 5;
}

gint a_foo (Fooable *self, gdouble quux) {
    return A_GET_CLASS(self)->foo(self, quux);
}

void implement_fooable (FooableIface *iface) {iface->foo = a_foo;}
void a_class_init      (AClass *cls)         {cls->foo = a_foo_real;}
void a_init            (A *self)             {}

G_DEFINE_TYPE_WITH_CODE(A, a, G_TYPE_OBJECT,
    G_IMPLEMENT_INTERFACE(TYPE_FOOABLE, implement_fooable));

/* derive class B from A  */
typedef struct {A parent;} B;
typedef struct {AClass parent;} BClass;

#define TYPE_B (b_get_type())

gint b_foo_real (Fooable *self, gdouble quux) {
    g_print("b_foo_real(%g)\n", quux);
    return 55;
}

void b_class_init (BClass *cls) {A_CLASS(cls)->foo = b_foo_real;}
void b_init       (B *self)     {}

G_DEFINE_TYPE(B, b, TYPE_A);

int main () {
    g_type_init();
    A *a = g_object_new(TYPE_A, NULL);
    B *b = g_object_new(TYPE_B, NULL);
    fooable_foo(FOOABLE(a), 87.0); // a_foo_real(87.0) and returns 5
    fooable_foo(FOOABLE(b), 32.0); // b_foo_real(32.0) and returns 55
    return 0;
}

これは、私ができる限り簡単な例です。関数を呼び出すと、実際に呼び出す関数を決定するために A クラスの vtable を参照するfooable_foo()インターフェイスを実装したときに定義された関数の vtable が参照されます。a_foo()B クラスの定義は、A クラスの定義a_foo_real()を独自のものでオーバーライドします。B クラスb_foo_realを連鎖させる必要がある場合、それは簡単A_CLASS(b_parent_class)->foo()です (G_DEFINE_TYPE マクロで定義されているものを使用します)。

于 2010-02-16T17:19:16.970 に答える