====== Grundlegende Deklaration im Header ====== Willkommen zum kleinen Tutorial zu GObject. Ganz nach den klassischen Tutorials zu objektorientierter Programmierung (OOP) werden wir eine Klasse ''Tier'' erstellen. **Hinweis:** Dies ist __kein__ OOP-Tutorial. Grundlagen zur objektorientierten Programmierung werden vorausgesetzt! ===== Vorarbeiten ===== Deklaration und Implementierung einer Klasse werden bei der Arbeit mit GObject auf zwei Dateien aufgeteilt (wie es ohne OOP in C auch ist): * tutorial-tier.h * tutorial-tier.c Bitte achtet bei Code-Beispielen immer darauf, in welcher dieser beiden Dateien dieser steht! ===== Namensrichtlinien ===== Mit der Zeit haben sich bei den Entwicklern, die mit GObject zu tun hatten, bestimmte Richtlinien entwickelt, an die wir uns auch halten sollten. Das wichtigste für uns grob zusammengefasst: * Um Namenskonflikte zu vermeiden, bekommt jede Klasse ein Präfix. Üblicherweise ist das der Name der Library oder der Anwendung. * Jede Memberfunktion folgt dem Namensprinzip: ''__'' Zum Nachlesen: [[http://library.gnome.org/devel/gobject/stable/gtype-conventions.html|Conventions]] ===== Das Grundgerüst ===== tutorial-tier.h /* * Copyright- und Lizenzinformationen */ /* * Header guard */ #ifndef __TUTORIAL_TIER_H__ #define __TUTORIAL_TIER_H__ #include /* * GType Makros */ #define TUTORIAL_TYPE_TIER (tutorial_tier_get_type()) #define TUTORIAL_TIER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TUTORIAL_TYPE_TIER, TutorialTier)) #define TUTORIAL_IS_TIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TUTORIAL_TYPE_TIER)) #define TUTORIAL_TIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TUTORIAL_TYPE_TIER, TutorialTierClass)) #define TUTORIAL_IS_TIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TUTORIAL_TYPE_TIER)) #define TUTORIAL_TIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TUTORIAL_TYPE_TIER, TutorialTierClass)) typedef struct _TutorialTier TutorialTier; typedef struct _TutorialTierClass TutorialTierClass; struct _TutorialTier { GObject parent_instance; }; struct _TutorialTierClass { GObjectClass parent_class; }; GType tutorial_tier_get_type(void); /* * Platz für Methoden. */ #endif \\ **Hinweis:** Kein Bezeichner sollte ''class'' heißen, da dies ein C++ Schlüsselwort ist! Wie zu sehen, bedarf es bei der Deklaration einer Klasse ein wenig mehr Aufwand als bei objektorientierten Sprachen wie C++ oder Java. ==== Die Makros ==== Am seltsamsten mögen euch vielleicht die sechs Makros zu Beginn des Headers scheinen: ^Makro^Funktion^ |''TUTORIAL_TYPE_TIER''|Liefert den ''GType'' der Klasse wieder.| |''TUTORIAL_TIER''|Cast für Instanzen, um innerhalb der Vererbungshierarchie auf Member zuzugreifen.| |''TUTORIAL_IS_TIER''|Typüberprüfung für Instanzen.| |''TUTORIAL_TIER_CLASS''|Cast für Klassenbeschreibung, um innerhalb der Vererbungshierarchie auf Klasseneigenschaften (z.B. Properties) zuzugreifen| |''TUTORIAL_IS_TIER_CLASS''|Typüberprüfung Klassenbeschreibung.| |''TUTORIAL_TIER_GET_CLASS''|Liefert die Klassenbeschreibung (''TutorialTierClass'') einer Instanz (''TutorialTier'') wieder.| ==== Die Strukturen ==== Auch müsste euch auffallen, dass wie zwei Structs deklariert haben (und das auch immer tun müssen...): ^Struct^Funktion^ |''TutorialTier''|Instanz. Eine Variable diesen Typs entspricht einer Instanz einer Klasse. Variablen innerhalb der Struktur entsprechen Memebervariablen (zu privaten Membern siehe unten)| |''TutorialTierClass''|Klassenbeschreibung. Diese Struktur speichert Daten zur Klasse, z.B. Properties und Signals.| ===== Private Member ===== Aus objektorientierten Sprachen dürfte euch wohl das Schlüsselwort **''private''** bekannt sein. Für die Umsetzung mit GObject gibt es zwei mögliche Varianten: ==== Die GTK+ Variante ==== Diese Variante findet man vorwiegend im Code zu GTK+. Bei ihr werden private Variablen nur durch Kommentare als solche gekennzeichnet: struct _TutorialTier { GObject parent_instance; /* < private > */ gint gehirn_masse; }; ==== Die Nautilus Variante ==== Diese Variante kam erstmals im Code zum Dateimanager Nautilus vor. Mittlerweile ist sie mehr oder weniger Standard, aus diesem Grund werden wir diese Methode verwenden. Hierbei werden alle privaten Variablen in eine eigene Struktur gepackt, die dann später in der ''.c''-Datei definiert wird. Die Liste der ''typedef''s wird um einen Eintrag ergänzt: typedef struct _TutorialTierPrivate TutorialTierPrivate; \\ Und die ''_TutorialTier''-Struktur bekommt eine neue Variable: struct _TutorialTier { GObject parent_instance; TutorialTierPrivate* priv; };\\ **Hinweis:** Die Variable sollte __nicht__ ''private'' genannt werden, da dies ein C++ Schlüsselwort ist. ===== Der fertige Header ===== Mit privaten Feldern sieht unser "nackter" Header nun so aus: tutorial-tier.h #ifndef __TUTORIAL_TIER_H__ #define __TUTORIAL_TIER_H__ #include /* * GType Makros */ #define TUTORIAL_TYPE_TIER (tutorial_tier_get_type()) #define TUTORIAL_TIER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TUTORIAL_TYPE_TIER, TutorialTier)) #define TUTORIAL_IS_TIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TUTORIAL_TYPE_TIER)) #define TUTORIAL_TIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TUTORIAL_TYPE_TIER, TutorialTierClass)) #define TUTORIAL_IS_TIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TUTORIAL_TYPE_TIER)) #define TUTORIAL_TIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TUTORIAL_TYPE_TIER, TutorialTierClass)) typedef struct _TutorialTier TutorialTier; typedef struct _TutorialTierClass TutorialTierClass; typedef struct _TutorialTierPrivate TutorialTierPrivate; struct _TutorialTier { GObject parent_instance; TutorialTierPrivate* priv; }; struct _TutorialTierClass { GObjectClass parent_class; }; GType tutorial_tier_get_type(void); /* * Platz für Methoden. */ #endif ====== ======
**[[gui:gtk:start|hoch zur Startseite]] || [[ gui:gtk:gobject:implementation |weiter]]**
\\