C Programming/GObject

From Wikibooks, open books for an open world
Jump to: navigation, search
Previous: Mixing languages Index Next: Code library

Since the C Programming-Language was not created with Object Oriented Programming in mind, it has no support for classes, inheritance, polymorphism and other OO Concepts. Neither does it have its own Virtual Table, which is found in object-oriented languages such C++, Java and C#. Therefore, it is nearly impossible to use an object-oriented programming paradigm with only C's language features and standard library. Since C was never intended to be an OOP Language, lack of Object-Orientation cannot be called a weakness or a flaw in the programming language itself, but it does sometimes limit the use and functionality of the language. In most cases, however, object-orientation and most OO Concepts can be achieved using third-party libraries. There are many third-party libraries designed to add support for object-oriented programming in C. The most general-purpose and widely used among these is the GObject System, which is part of Glib. The GObject System comes with its own virtual table. To create an object in C using the GObject system, it has to be sub-classed from the GObject struct.

Object-Creation[edit]

In this example a new object will be implemented directly derived from GObject. For simplicity, the object is named MyObject.

Declaring An Object[edit]

To create a simple object, two structs must be declared. The instance and the class. They are usually declared in this manner:

/* in myobject.h */
typedef struct _MyObject MyObject;
typedef struct _MyObjectClass MyObjectClass;
 
struct _MyObject
{
  GObject parent_instance;
 
  /* instance members */
};
 
struct _MyObjectClass
{
  GObjectClass parent_class;
 
  /* class members */
};

Boiler-Plate Code[edit]

Since the GObject System is just a third-party library and therefore cannot make any changes to the C Language itself, creating a new object requires a lot of boiler-plate code.

/* in myobject.h */
#define MY_TYPE_OBJECT                   (my_object_get_type ())
#define MY_OBJECT(obj)                   (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_OBJECT, MyObject))
#define MY_IS_OBJECT(obj)                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_OBJECT))
#define MY_OBJECT_CLASS(_class)          (G_TYPE_CHECK_CLASS_CAST ((_class), MY_TYPE_OBJECT, MyObjectClass))
#define MY_IS_OBJECT_CLASS(_class)       (G_TYPE_CHECK_CLASS_TYPE ((_class), MY_TYPE_OBJECT))
#define MY_OBJECT_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_OBJECT, MyObjectClass))


Defining The Object[edit]

Before use, the newly created object must be defined.

/* in myobject.c */
 
G_DEFINE_TYPE(MyObject, my_object, G_TYPE_OBJECT);

Static Functions[edit]

There are a few static functions that may or may not to be defined, depending on your object. For a minimal object these ones are compulsory:

/* in myobject.c */
static void my_object_class_init(MyObjectClass *_class) 
{
     /* code */
}
 
static void my_object_init(MyObject* obj)
{
     /* code */
}


The Constructor[edit]

There is no internal way of allocating memory for an object in C. Therefore an explicit constructor must be declared for the new object.

/* in myobject.c */
 
GObject* my_object_new(void)
{
     return g_object_new(MY_TYPE_OBJECT , 0);
}


Object-Usage[edit]

Although creating the object using its own pointer-type is perfectly valid, it is recommended to use the pointer-type of the object at the top of the hierarchy i.e the furthest off base class. The newly created object may now be used like this:

/* in main.c */
 
/* Note: GObject is at the top of the hierarchy. */
 
/* declaration and construction */
GObject* myobj = my_object_new(); 
 
/* destruction */
g_object_unref(myobj);

Inheritance[edit]

Concept[edit]

Inheritance is one of the most widely used and useful OO Concepts. It provides an efficient way to reuse existing code by wrapping it up into an object and then sub-classing it. The new classes are known as derived classes. Many object hieriarchies can be created using inheritance. Inheritance is also one of the most efficient ways of abstracting code.

Implementation[edit]

In the GObject System, inheritance can be achieved by sub-classing GObject. Since C provides no keyword or operator for inheritance, a derived object is usually made by declaring the base instance and base class as a member of the derived instance and derived class respectively. In C code:

/* derived object instance */
struct DerivedObject
{
     /* the base instance is a member of the derived instance */
     BaseObject parent_instance;
};
 
/* derived object class */
struct DerivedObjectClass
{
    /* the base class is a member of the derived class */
    BaseObjectClass parent_class;
};