gm********@yahoo.com wrote:
It's been mentioned to me that, in standard c, that you can have
structures behave very much like classes in relation to something to do
with function calls within a structure.
Now, I didn't get the details, but does someone have a clue of what
this person perhaps was talking about? Do you think he just ment
something such as function pointers? Or could I, much like a C++
Class, call a class function that has access to the structure it's
associated with, without including a pointer refrence to the object as
one of the variables of the function?
This will be coded on a Sun/Solaris system using Forte 5.0, by the
way if that's important. I can't use explicit C++ with this project
but if I can use c and have it work a lot like C++ that would be great.
Tony
You can define interfaces like this:
// In a header file you do:
struct interface; // forward declaration
// Define a LIST data type for holding linked lists
typedef struct tagList {
struct interface * lpVtbl; // Pointer to the function table
// Data fields
struct tagList *PointerToLastElement;
struct tagList *FirstElement;
int NumberOfElements;
} LIST;
// Define the function table (methods)
struct interface {
int (*Append)(LIST *L,void *data);
void *(*First)(LIST *L);
void *(*Last)(LIST *L);
void *(*Remove)(LIST *L);
int (*Length)(LIST *L);
// Just an example. Many functions are missing
// But you get the idea.
};
// Now, in an implementation file you do:
static int Append(LIST *L,void *data)
{ // Implementation omitted }
static void *First(LIST *L)
{ // Implementation omitted }
static void *Last(LIST *L)
{ // Implementation omitted }
static void *Remove(LIST *L)
{ // Implementation omitted }
static int Length(LIST *L)
{ // Implementation omitted }
// Define a static struct interface holding
// function pointers to the implementation.
static struct interface {
First, Last,
Remove, Length
} MethodTable;
// Define the constructor.
LIST *newList(int NumberOfElements)
{
LIST *result;
result = malloc(sizeof(LIST));
if (result) {
memset(result,0,sizeof(LIST));
// assign the method table
result->lpVtbl = & MethodTable;
// assign the other fields
}
return result;
}
AND NOW (at last) you use it like this:
#include "list.h"
int main(void)
{
LIST *myList = newList(12);
myList->lpVtbl->Append(myList,"Element1");
myList->lpVtbl->Append(myList,"Element2");
int d = myList->lpVtbl->Length(myList); // Should be 2
}
This is quite powerful since you can at any time replace
those function pointers by a function of your own (subclassing)
but you can keep a copy of the function pointer to call the
original method either before or after or in between your
own subclassed method, what you can't do in C++.
C is more explicit than C++, and there is no compiler help.
This is less of a problem than what it seems at first sight,
and MUCH more powerful. You are in control. There is no
black box of a compiler to keep you from doing what you want.
Also, there are no rules other than the rules you decide to follow.
Of course this can be used constructively or can lead to code
that is impossible to follow. It is up to you.
For an example of this kind of programming see the source code
of the container library in lcc-win32.
http://www.cs.virginia.edu/~lcc-win32.