Badman Temat założony przez niniejszego użytkownika |
Programowanie obiektowe w C » 2012-11-02 11:02:41 A jednak się da programować obiektowo w C:) przy użyciu GObject Problem typowo uczelniany klasa Osoba i klasa Student, która dziedziczy po klasie Osoba. Tak naprawdę klasa Osoba ma już pewną funkcjonalność ponieważ tak naprwdę dziedziczy po klasie GObject. Na potrzeby przykładu wszystko zbite w jednym pliku #include <glib.h> #include <glib-object.h>
G_BEGIN_DECLS
#define OSOBA_TYPE (osoba_get_type ()) #define OSOBA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSOBA_TYPE, Osoba)) #define OSOBA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), OSOBA_TYPE, OsobaClass)) #define OSOBA_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSOBA_TYPE)) #define OSOBA_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), OSOBA_TYPE)) #define OSOBA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), OSOBA_TYPE, OsobaClass))
typedef struct _OsobaClass OsobaClass; typedef struct _Osoba Osoba;
struct _OsobaClass { GObjectClass parent_class; };
struct _Osoba { GObject parent_instance; gchar * imie; gchar * nazwisko; guint wiek; };
GType osoba_get_type( void );
void osoba_set_nazwisko( Osoba * obj, const gchar * tekst );
G_END_DECLS
enum { PROP_0, PROP_IMIE, PROP_NAZWISKO, PROP_WIEK };
static void osoba_init( Osoba * osoba, gpointer g_class ) { osoba->wiek = 0; }
static void osoba_set_property( GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec ) { Osoba * osoba; guint nr; const gchar * imie; g_return_if_fail( OSOBA_IS( object ) ); osoba = OSOBA( object ); switch( prop_id ) { case PROP_IMIE: imie = g_value_get_string( value ); if( osoba->imie ) g_free( osoba->imie ); osoba->imie = g_strdup( imie ); break; case PROP_NAZWISKO: osoba_set_nazwisko( osoba, g_value_get_string( value ) ); break; case PROP_WIEK: nr = g_value_get_uint( value ); if( osoba->wiek != nr ) { osoba->wiek = nr; } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); break; } }
static void osoba_get_property( GObject * object, guint prop_id, GValue * value, GParamSpec * pspec ) { Osoba * osoba; g_return_if_fail( OSOBA_IS( object ) ); osoba = OSOBA( object ); switch( prop_id ) { case PROP_IMIE: g_value_set_string( value, osoba->imie ); break; case PROP_NAZWISKO: g_value_set_string( value, osoba->nazwisko ); break; case PROP_WIEK: g_value_set_uint( value, osoba->wiek ); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); break; } }
static void osoba_class_init( OsobaClass * klass ) { GObjectClass * object_class = G_OBJECT_CLASS( klass ); object_class->set_property = osoba_set_property; object_class->get_property = osoba_get_property; g_object_class_install_property( object_class, PROP_IMIE, g_param_spec_string( "imie", "imie-set", "Ustawia / pobiera imie", NULL, G_PARAM_READABLE | G_PARAM_WRITABLE ) ); g_object_class_install_property( object_class, PROP_NAZWISKO, g_param_spec_string( "nazwisko", "nazwisko-set", "Ustawia / pobiera nazwisko", NULL, G_PARAM_READABLE | G_PARAM_WRITABLE ) ); g_object_class_install_property( object_class, PROP_WIEK, g_param_spec_uint( "wiek", "wiek-set", "Ustawia / pobiera wiek", 0, 100, 0, G_PARAM_READABLE | G_PARAM_WRITABLE ) ); }
void osoba_set_nazwisko( Osoba * obj, const gchar * tekst ) { gchar * nowy; nowy = g_strdup( tekst ); if( obj->nazwisko ) g_free( obj->nazwisko ); obj->nazwisko = nowy; }
GType osoba_get_type( void ) { static GType osoba_type = 0; if( !osoba_type ) { static const GTypeInfo osoba_info = { sizeof( OsobaClass ), ( GBaseInitFunc ) NULL, ( GBaseFinalizeFunc ) NULL, ( GClassInitFunc ) osoba_class_init, NULL, NULL, sizeof( Osoba ), 0, ( GInstanceInitFunc ) osoba_init }; osoba_type = g_type_register_static( G_TYPE_OBJECT, "Osoba", & osoba_info, 0 ); } return osoba_type; }
G_BEGIN_DECLS
#define STUDENT_TYPE (student_get_type ()) #define STUDENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STUDENT_TYPE, Student)) #define STUDENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), STUDENT_TYPE, StudentClass)) #define STUDENT_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STUDENT_TYPE)) #define STUDENT_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), STUDENT_TYPE)) #define STUDENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), STUDENT_TYPE, StudentClass))
typedef struct _StudentClass StudentClass; typedef struct _Student Student;
struct _StudentClass { OsobaClass parent_class; };
struct _Student { Osoba parent_instance; guint numer_indeksu; };
GType student_get_type( void );
G_END_DECLS
enum { PROP_STUDENT_0, PROP_NUMER_INDEKSU };
G_DEFINE_TYPE( Student, student, OSOBA_TYPE );
static void student_init( Student * osoba ) { }
static void student_set_property( GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec ) { Student * student; guint nr; g_return_if_fail( STUDENT_IS( object ) ); student = STUDENT( object ); switch( prop_id ) { case PROP_NUMER_INDEKSU: nr = g_value_get_uint( value ); if( student->numer_indeksu != nr ) student->numer_indeksu = nr; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); break; } }
static void student_get_property( GObject * object, guint prop_id, GValue * value, GParamSpec * pspec ) { Student * student; g_return_if_fail( STUDENT_IS( object ) ); student = STUDENT( object ); switch( prop_id ) { case PROP_NUMER_INDEKSU: g_value_set_uint( value, student->numer_indeksu ); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID( object, prop_id, pspec ); break; } }
static void student_class_init( StudentClass * klass ) { GObjectClass * object_class = G_OBJECT_CLASS( klass ); object_class->set_property = student_set_property; object_class->get_property = student_get_property; g_object_class_install_property( object_class, PROP_NUMER_INDEKSU, g_param_spec_uint( "indeks", "wiek-set", "ustawia_numer", 0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_WRITABLE ) ); }
int main( int argc, char * argv[] ) { Osoba * osoba; gchar * nazwisko, * imie; guint wiek, nr; Student * student; g_type_init(); osoba = g_object_new( OSOBA_TYPE, NULL ); g_object_get( osoba, "nazwisko", & nazwisko, "imie", & imie, "wiek", & wiek, NULL ); g_print( "Obiekt Osoba zawiera: Nazwisko: %s, Imie: %s, wiek: %d\n", nazwisko, imie, wiek ); g_object_set( osoba, "wiek", 5, "imie", "Pawel", NULL ); osoba_set_nazwisko( osoba, "Zak" ); g_object_get( osoba, "nazwisko", & nazwisko, "imie", & imie, "wiek", & wiek, NULL ); g_print( "Obiekt Osoba zawiera: Nazwisko %s, Imie: %s, wiek: %d\n", nazwisko, imie, wiek ); student = g_object_new( STUDENT_TYPE, "indeks", 16722, NULL ); g_object_get( student, "nazwisko", & nazwisko, "imie", & imie, "wiek", & wiek, "indeks", & nr, NULL ); g_print( "Obiekt Student zawiera: Nazwisko: %s, Imie: %s, wiek: %d, numer indeksu: %d\n", nazwisko, imie, wiek, nr ); g_object_set( student, "imie", "Mirek", "nazwisko", "Nowak", NULL ); g_object_set( student, "wiek", 18, NULL ); g_object_get( student, "nazwisko", & nazwisko, "imie", & imie, "wiek", & wiek, "indeks", & nr, NULL ); g_print( "Obiekt Student zawiera: Nazwisko: %s, Imie: %s, wiek: %d, numer indeksu: %d\n", nazwisko, imie, wiek, nr ); return 0; }
|