Unc*_*eiv 58
第一个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
Run Code Online (Sandbox Code Playgroud)
这些函数可以作为函数指针的结构的一部分,因此像p-> call(p)这样的语法变得可能,但你仍然必须显式地将指向结构的指针传递给函数本身.
Pet*_*aný 51
常见的方法是使用指向函数的指针定义struct.这定义了可以在任何类型上调用的"方法".子类型然后在这个公共结构中设置它们自己的函数,并返回它.
例如,在linux内核中,有struct:
struct inode_operations {
int (*create) (struct inode *,struct dentry *,int, struct nameidata *);
struct dentry * (*lookup) (struct inode *,struct dentry *,
struct nameidata *);
...
};
Run Code Online (Sandbox Code Playgroud)
每个注册的类型的文件系统的随后登记其自己的功能create
,lookup
和其余功能.其余代码可以使用泛型inode_operations:
struct inode_operations *i_op;
i_op -> create(...);
Run Code Online (Sandbox Code Playgroud)
thi*_*ing 29
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;
Run Code Online (Sandbox Code Playgroud)
要调用方法:
int CallSomeFunction(TheClass* this, int i)
{
(this->pVTable->SomeFunction)(this, i);
}
Run Code Online (Sandbox Code Playgroud)
小智 15
我查看了所有人的答案并提出了这个问题:
#include <stdio.h>
typedef 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;
}
Run Code Online (Sandbox Code Playgroud)
我希望能回答一些问题.
Séb*_*rra 12
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); \
})
Run Code Online (Sandbox Code Playgroud)
在同一个文档,有一个看看object
,vtable
,vtable_delegated
和symbol
结构,以及_bind
和vtable_lookup
功能.
干杯!