有没有办法在C
编程语言中编写类似OO的代码?
也可以看看:
你能用C编写面向对象的代码吗?
C中的面向对象
通过搜索"[c] oo"找到.
第一个C++编译器("C with classes")实际上会生成C代码,所以这绝对可行.
基本上,你的基类是一个结构; 派生结构必须在第一个位置包含基本结构,因此指向"derived"结构的指针也将是指向基本结构的有效指针.
typedef struct { data member_x; } base; typedef struct { struct base; data member_y; } derived; void function_on_base(struct base * a); // here I can pass both pointers to derived and to base void function_on_derived(struct derived * b); // here I must pass a pointer to the derived class
这些函数可以作为函数指针的结构的一部分,因此像p-> call(p)这样的语法变得可能,但你仍然必须显式地将指向结构的指针传递给函数本身.
常见的方法是使用指向函数的指针定义struct.这定义了可以在任何类型上调用的"方法".子类型然后在这个公共结构中设置它们自己的函数,并返回它.
例如,在linux内核中,有struct:
struct inode_operations { int (*create) (struct inode *,struct dentry *,int, struct nameidata *); struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); ... };
每个注册的类型的文件系统的随后登记其自己的功能create
,lookup
和其余功能.其余代码可以使用泛型inode_operations:
struct inode_operations *i_op; i_op -> create(...);
C++离C不远.
类是具有指向名为VTable的函数指针表的隐藏指针的结构.Vtable本身是静态的.当类型指向具有相同结构的Vtables但指针指向其他实现时,您将获得多态性.
建议将调用逻辑封装在以struct为参数的函数中,以避免代码混乱.
您还应该在函数中封装结构实例化和初始化(这相当于C++构造函数)和删除(C++中的析构函数).无论如何这些都是很好的做法.
typedef struct { int (*SomeFunction)(TheClass* this, int i); void (*OtherFunction)(TheClass* this, char* c); } VTable; typedef struct { VTable* pVTable; int member; } TheClass;
要调用方法:
int CallSomeFunction(TheClass* this, int i) { (this->pVTable->SomeFunction)(this, i); }
我查看了所有人的答案并提出了这个问题:
#includetypedef struct { int (*get)(void* this); void (*set)(void* this, int i); int member; } TheClass; int Get(void* this) { TheClass* This = (TheClass*)this; return This->member; } void Set(void* this, int i) { TheClass* This = (TheClass*)this; This->member = i; } void init(TheClass* this) { this->get = &Get; this->set = &Set; } int main(int argc, char **argv) { TheClass name; init(&name); (name.set)(&name, 10); printf("%d\n", (name.get)(&name)); return 0; }
我希望能回答一些问题.
VPRI的Ian Piumarta和Alessandro Warth 的文章开放可重用对象模型的附录B是GNU C中的对象模型的实现,大约140行代码.这是一个迷人的读物!
这是使用GNU扩展到C(语句表达式)的向对象发送消息的宏的未缓存版本:
struct object; typedef struct object *oop; typedef oop *(*method_t)(oop receiver, ...); //... #define send(RCV, MSG, ARGS...) ({ \ oop r = (oop)(RCV); \ method_t method = _bind(r, (MSG)); \ method(r, ##ARGS); \ })
在同一个文档,有一个看看object
,vtable
,vtable_delegated
和symbol
结构,以及_bind
和vtable_lookup
功能.
干杯!