2016-04-22 24 views
0

Ich habe die GLib Klassen Foo und DerivedFoo.Wie behandelt man den "inkompatiblen Zeigertyp" bei der Zuweisung von virtuellen Methoden in einer abgeleiteten Klasse?

Die Foo Klasse hat eine bar() Methode:

typedef struct _FooClass 
{ 
    GObjectClass parent_class; 

    void (*bar) (Foo *self); 
} FooClass; 

Die DerivedFoo Klasse leitet sich von Foo und implementiert die bar() Methode:

void derived_foo_bar (DerivedFoo *self); 

static void 
derived_foo_class_init (DerivedFooClass *klass) 
{ 
    FooClass *foo_class = FOO_CLASS (klass); 
    // Compiler warning appears here 
    foo_class->bar = derived_foo_bar; 
} 

Die Warnmeldung ist:

warning: assignment from incompatible pointer type 

Die Zeiger sind nicht kompatibel, da der Typ des self-Parameters unterschiedlich ist (Foo * vs. DerivedFoo *).

Ist dies der richtige Weg, um virtuelle Methoden in GObject zu implementieren?

Wenn ja, kann/sollte ich etwas gegen die Compiler-Warnung tun?

+1

Wie leitet sich 'DerivedFoo' von' Foo' ab? Es gibt keine Vererbung in C. – atturri

+0

Diese Frage ist ein guter Weg, um ein Argument über die [strenge Aliasing-Regel] zu starten (https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) . – user3386109

+0

Sie könnten es als 'foo_class-> bar = (void (*) (Foo *)) derived_foo_bar;'. Ich denke, eine vernünftige Verwendung von 'typedef' und/oder Makros würde es weniger hässlich aussehen lassen! –

Antwort

3

Sie verlassen den Funktionsprototyp, um die virtuelle Basisklasse zu respektieren, und geben ihn in Ihrer Funktion mit glib-Makros/-Funktionen an.

void derived_foo_bar (Foo *self); 

static void 
derived_foo_class_init (DerivedFooClass *klass) 
{ 
    FooClass *foo_class = FOO_CLASS (klass); 
    // Compiler warning appears here 
    foo_class->bar = derived_foo_bar; 
} 

void derived_foo_bar (Foo *_self) 
{ 
    DerivedFoo *self = DERIVED_FOO (self); /* or whatever you have named this macro, using the standard GLIB semantics */ 
/* If self is not compatible with DerivedFoo, a warning will be issued from glib typecasting logic */ 
}