how to program high level concepts (i.e. Object class, and Generics) in C
Here lately I've been tinkering around with my own languages as well as reading various writings on the subject.
Does anyone have any good advice on how, in C (or Assembler), do you program the concept of the Object Class
and/or the 开发者_Python百科concept of Generics
into a language. (referring to the Java implementations of Object and Generics)
For instance, in Java all all classes extend Object. So how do you represent this at the C level? is it something like:
#include <stdio.h>
typedef struct {
int stuff;
} Object;
typedef struct {
int stuff;
Object object;
} ChildClass;
int main() {
ChildClass childClass;
childClass.stuff = 100;
childClass.object.stuff = 200;
printf("%d\n", childClass.stuff);
printf("%d\n", childClass.object.stuff);
}
And I'm not really even sure how to get started with implementing something like Generics. I also appreciate any valuable links regarding program langauge design. Thanks,
Take a look at Structure and Interpretation of Computer Programs by Abelson and Sussman. While it doesn't show how to do it in C, it does demonstrate how to create types at run time and how to build an object system on top of a language that doesn't provide native support. Once you understand the basic ideas, you should be able to use structs and function pointers to create an implementation. Of course, looking at the source code for a C++ preprocessor will also be instructive. At one time, C++ was just a preprocessor for a C compiler.
I found this book a little while ago that has been an interesting read: Object-Oriented Programming With ANSI-C (PDF).
In C I've created class-like structures and methods by using struct
s (to store the class's state) and functions that take pointers to them (methods of the class). Implementing things like inheritance is possible, but would get messy fast. I'm not a Java guy though, and I'm not sure how much of Java you should press onto C, they are very different languages.
Here's probably the crudest form of a object implementation possible; I wrote it to run multiple PID controls at the same time.
//! PID control system state variables
typedef struct {
const PID_K * K; //!< PID control parameters
int32_t e; //!< Previous error (for derivative term)
int32_t i; //!< Integrator
} PID_SYS;
void PID_Init(PID_SYS * sys, const PID_K * K)
{
sys->i = 0;
sys->e = 0;
sys->K = K;
}
int16_t PID_Step(PID_SYS * sys, int32_t e)
{
// ...PID math using "sys->" for any persistent state variables...
}
If your goal is to write a new language that incorporates high level concepts, you might want to look at the CPython sources. CPython is an object oriented programming language whose interpreter is written in C. Open source C implementations of compilers/interpreters for C++, D, Javascript, Go, Objective C, and many, many others exist as well.
It's more complicated, but you're on the right path. Actual implementations use roughly the same code as yours to achieve inheritance (but they actually use containment to do it, which is quite ironic), along with a per-instance table of function pointers (virtual functions) and some (okay, many) helper macros.
See gobject.
It's definitely not C, but I'd recommend taking a look at Lua.
At its core, Lua only has a few basic types: number, string, boolean, function, and table (there's a couple more outside of the scope of this topic, though. A table is essentially just a hashtable that accepts keys of any type and can contain values of any type as well.
You can implement OOP in Lua by way of metatables. In Lua, a table is allowed to have up to one metatable, which is accessed under special circumstances, such as when a table is added or multiplied to another table or when you try to access a key that is not present in the table.
Using metatables, you can quickly and easily achieve something quite like inheritance by chaining together multiple metatables. When you try to access a missing key in a table, Lua looks up a key named __index
in that table's metatable. So if you try to access a key named foo
on a table that doesn't have such a key, Lua will check for foo
in the first metatable. If it isn't present there and that metatable has a metatable of its own with __index
defined, it will check for foo
in the next one, and so on.
Once you realize how simple it is to do this in Lua, translating it to C is very achievable. Your OOP will be completely at run-time, of course, but it will be very OOP-like indeed.
精彩评论