Ale*_*lex 1 c embedded struct class
我正在尝试用 C 语言创建一个“类模型”,其中我定义了一个struct代表类的对象,并在其中定义了函数指针来代表方法,如下所示:
//ClassName.h
typedef struct struct_ClassName ClassName;
struct ClassName
{
char a;
char b;
char c;
void (*method1)(ClassName*, char);
void (*method2)(ClassName*, char);
...
void (*methodN)(ClassName*, char);
};
void initClassName(ClassName*);
Run Code Online (Sandbox Code Playgroud)
//ClassName.c
#include "ClassName.h"
static void method1(ClassName *this_c, char c);
static void method2(ClassName *this_c, char c);
...
static void methodN(ClassName *this_c, char c);
void initClassName(ClassName *this_c)
{
this_c->method1 = &method1;
this_c->method2 = &method2;
...
this_c->methodN = &methodN;
}
void method1(ClassName *this_c, char c)
{
//do something
}
void method2(ClassName *this_c, char c)
{
//do something
}
...
void methodN(ClassName *this_c, char c)
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
一切正常,但是在代码中的某个地方,我定义了一个数组:
...
ClassName objects[200];
for(i = 0; i < 200; i++)
{
initClassName(&objects[i]);
}
...
Run Code Online (Sandbox Code Playgroud)
由于函数指针的原因,与该数组关联的内存使用量相当高(我在这个“类”中有几个“方法”)。
考虑到这是将在嵌入式系统中运行的代码,是否有更好的方法来做到这一点?
在结构之外定义函数可能是一种可能性,但在我看来,它不尊重我试图模仿的内容。
我必须只使用 C,而不是 C++ 。
您创建的是一个非常动态的系统,其中每个对象实例都可以有自己的一组方法实现。这就是它使用这么多内存的原因。
另一种方法是更接近早期 C++(多重继承之前)的实现,其中同一类的所有实例共享相同的vtable。vtable包含函数指针。
typedef struct struct_ClassName ClassName;
typedef struct struct_ClassName_vtable ClassName_vtable;
struct ClassName_vtable
{
void (*method1)(ClassName*, char);
void (*method2)(ClassName*, char);
...
void (*methodN)(ClassName*, char);
}
struct ClassName
{
ClassName_vtable* _vtable;
char a;
char b;
char c;
};
void initClassName(ClassName*);
Run Code Online (Sandbox Code Playgroud)
static void method1(ClassName *this_c, char c);
static void method2(ClassName *this_c, char c);
...
static void methodN(ClassName *this_c, char c);
ClassName_vtable _ClassName_vtable = {
method1,
method2,
...,
methodN
};
void initClassName(ClassName *this_c)
{
this_c->_vtable = _ClassName_vtable;
}
Run Code Online (Sandbox Code Playgroud)
这样,每个实例的 OO 开销仅为指针的大小。创建子类也更容易。
方法调用如下所示:
ClassName* obj = ...;
obj->vtable->method2(obj, 'a');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |