Now that you know how an interface is defined in C, let us see how to implement a hypothetical PODSCounter
object: a PODS object that implements the PODSCounter
interface. One possible implementation would be:
typedef struct MyPODSCounter { PODSCounter base; PODSInt32 count; } MyPODSCounter; static void MySetCount(PODSCounter* c, PODSInt32 newCount) { MyPODSCounter* m = (MyPODSCounter* ) c; m->count = newCount; } static PODSInt32 MyGetCount(PODSCounter* c) { MyPODSCounter* m = (MyPODSCounter* ) c; return m->count; } static void MyIncrement(PODSCounter* c) { MyPODSCounter* m = (MyPODSCounter* ) c; ++m->count; } PODSCounter* MyCounterNew() { static PODSCounterVTable* vtable; MyPODSCounter* m; if (!vtable) { vtable = (PODSCounterVTable* ) malloc(sizeof(PODSCounterVTable)); vtable->m_setCount = &MySetCount; vtable->m_getCount = &MyGetCount; vtable->m_increment = &MyIncrement; } m = (MyPODSCounter* ) malloc(sizeof(MyPODSCounter)); m->base.vtable = vtable; m->count = 0; return &m->base; } |
In this example, the MyPODSCounter
structure is used to store objects that implement the PODSCounter
interface. The MyPODSCounter
structure extends the PODSCounter
structure by including a PODSCounter
as its first element.
MyPODSCounter
adds a field I
to hold the actual count in this particular PODSCounter
implementation. The field I
is private to the MyPODSCounter
implementation: it is not visible to code that uses the PODSCounter
structure.
The above methods MySetCount
, MyGetCount
, and MyIncrement
implement each of the methods defined by the PODSCounter
interface. Each of these methods takes a PODSCounter
, not a MyPODSCounter
, as its first argument, so that each method's definition matches its method definition in the PODSCounterVTable
structure. Each of these methods can only be called with a MyPODSCounter
object, so each method uses a typecast to convert the method's first argument to a MyPODSCounter
. This is a common design pattern in code used to implement a PODS interface.
The method MyCounterNew
is used to create a new MyPODSCounter
object that implements the PODSCounter
interface. The MyCounterNew
method returns a PODSCounter
, not a MyPODSCounter
. The structure MyPODSCounter
is private to the implementation and callers would use a MyPODSCounter
object only by accessing its methods through the PODSCounter
interface. The static variable vtable
holds a vtable that is shared by all MyPODSCounter
objects. Vtables should be shared among objects of the same class.
In this example, you could create a new vtable for each MyPODSCounter
object, but that would only waste space, because all MyPODSCounter
vtables would contain the same data and never would change.
You cannot use a static variable in a POD on devices running Palm OS, where PODS cannot have any global or static data. For more information, see Coding without globals on Palm OS.
The last line of the method newMyCounter()
converts a MyPODSCounter*
into a PODSCounter*
by taking the address of the PODSCounter
structure, which is the first element of MyPODSCounter
. Alternatively, you could write:
return (PODSCounter* ) m; |
Send feedback about this page using email. | Copyright © 2008, iAnywhere Solutions, Inc. |