Reputation: 839
How can you program to an interface in C as you would in Go?
Go code:
package measure
type Weighable interface {
Weigh() float64
}
func Weight(w Weighable) float64 {
return w.Weigh()
}
Now any type which has a Weigh() method that returns a float64 is considered "Weighable".
package planet
type Info struct {
volume float
density float
}
func (own *Info) Weigh() float64 {
return own.volume * own.density
}
So because a planet is Weighable, I can Weigh() it.
package main
import "measure", "planet"
func main() {
Earth := &planet.Info{1097509500, 5.51}
EarthWeight = measure.Weight(Earth)
}
Now anything, a person or a subatomic particle, may be weighed differently, but can be invoked using the same code, measure.Weight(Person) or measure.Weight(subatomicParticle)
Question:
Header files, which define function signatures, seems to be the right way to proceed, but what about the function which takes an interface as an argument? Can this be done in C, or is there a better way?
Upvotes: 0
Views: 179
Reputation: 176
In C, you can implement a funtion table like this (in fact, OLE technologies are implemented using this principle):
typedef struct tagOBJECT OBJECT;
// This is the interface
typedef struct tagIVTABLE {
int (*getData)(OBJECT* This);
void (*setData)(OBJECT* This, int i);
}IVTABLE;
typedef struct tagOBJECT {
IVTABLE* lpVtbl;
int data;
} OBJECT;
int someGetFunction(OBJECT* This) {
return This->data;
}
void someSetFunction(OBJECT* This, int i) {
This->data = i;
}
int main(void)
{
IVTABLE Vtbl;
OBJECT obj;
OBJECT obj2;
Vtbl.getData = someGetFunction;
Vtbl.setData = someSetFunction;
// You would code this in a constructor function
obj.lpVtbl = &Vtbl;
obj2.lpVtbl = &Vtbl;
obj.lpVtbl->setData(&obj, 7);
printf("\n%d", obj.lpVtbl->getData(&obj));
obj2.lpVtbl->setData(&obj2, 77);
printf("\n%d", obj2.lpVtbl->getData(&obj2));
return 0;
}
Notice how the functions must have a pointer to the approproiate object ... C++ compilers generate this hidden parameter in instance methods and the keyword this refers to that parameter. This example is just to illustrate the principle. Hope it will help :-)
Upvotes: 2
Reputation: 53006
You can't. That's not how c programs are meant to be. If you want object oriented capabilities the closest thing to c is c++.
In c++ you can write class
es with pure virtual methods, they will not need an implementation in the class where you declare them as pure virtual
public:
virtual int pure_virtual_method() = 0;
// ^ this means PURE VIRTUAL
then any class that inherits from this class MUST implement pure_virtual_method()
.
This is exactly what an interface is for example as understood in the java language. You have a skeleton of a class with predefined but unimplemented method and you derive classes from that skeleton being forced to provide implementations to some methods. This is really elegant and is almost the only thing I love about c++.
Note: there is a Object Oriented c library I know of glib, but it's really cumbersome and I never really liked the way they make c "object oriented". Inheritance is possible but it's too complicated for my taste.
Upvotes: 4