多级继承递归 我有一个必须在C中的项目(只是为了避免使用C++参数)。
该项目依赖于虚拟表和指针来实现多态性 然而,我一直在从多级继承实现超级构造函数 一个示例结构是:多级继承递归 我有一个必须在C中的项目(只是为了避免使用C++参数)。,c,inheritance,C,Inheritance,该项目依赖于虚拟表和指针来实现多态性 然而,我一直在从多级继承实现超级构造函数 一个示例结构是: Base Object /\ /\ Constructed Object Simple Object /\ SpecificConstructed 所有对象都有一个名称和一个类。 例如,构造的对象可能具有子对象列表。 因为简单对象只能添加一个值 基本对象仅定义为: struct _object { struct
Base Object
/\ /\
Constructed Object Simple Object
/\
SpecificConstructed
所有对象都有一个名称和一个类。
例如,构造的对象可能具有子对象列表。
因为简单对象只能添加一个值
基本对象仅定义为:
struct _object {
struct _class *class;
char *name;
}
类是虚拟表所在的位置:
struct _class {
struct _class *super;
char *name;
size_t size;
void* (*init)(void *_this, char *name);
...
}
构造对象是:
struct _constructed_object {
struct _object base;
void* components; //a list of sub objects for example
}
struct _simple_object {
struct _object base;
unsigned char value; //a simple value for this specific type
}
简单对象示例如下:
struct _constructed_object {
struct _object base;
void* components; //a list of sub objects for example
}
struct _simple_object {
struct _object base;
unsigned char value; //a simple value for this specific type
}
所以每个对象都有一个类,类可以有超类,特别是对于SpecificConstructed->Constructed
我的定义如下:
struct _class base = {0, "Base", sizeof(struct _object), base_init};
struct _class constructed = {&base, "Constructed", sizeof(struct _constructed_object}, constructed_init};
struct _class specific = {&constructed, "SpecificConstructed", sizeof(struct _constructed_object), specific_init};
struct _class simple = {&base, "SimpleOBject", sizeof(struct _simple_object}, simple_init};
此定义允许我使用函数创建指定类的对象:
new(struct _class *a_class) {
...
struct _object *o = calloc(1, a_class->size);
o->class = a_class;
o = a_class->init(o);
return o;
}
如果我这样做的话:
new(SpecificConstructed)
New将创建适当的空间(sizeof(struct _constructed _object)),它将调用“specific _init”,这反过来将调用“constructed _init”(它是super),最后将调用“base _init”(它是super)。然而,流是特定的、构造的、特定的、构造的
我用于调用超级初始值设定项的函数:
void* super_init(void* _this, char *name){
struct _object *o = (struct _object*)_this;
const struct _class *c = o->class;
const struct _class *s = c->super;
return (s && s->init) ? s->init(_this, name) : _this;
}
简单的(to-super)基方法调用可以工作,因为我可以只调用supersinit
但是对于特定的构造,调用super会将我带到构造的对象,这是正确的步骤,但是它不会将我发送到base_init,而是将我发送回特定的_init调用。这是因为我传递了相同的_This对象,该对象以特定于类的开始,我理解这一点,但不确定如何修复它,以及是否确实可以修复它
我读过面向对象的C语言书,但它涉及到一级继承循环->点,而元类一章就在我脑海中飞过。IVE也查看Objto-C运行时,看看它是如何处理的,但它也有元类,我现在还不能理解。 < P>这是非常棒的东西,我在90年代初在C中做了一点那种东西,然后转到C++。 不幸的是,尽管你的问题很长,但它仍然有点模糊,因为它没有向我们展示某些东西,比如什么是“构造对象”(为什么这样称呼它),“构造对象”和“简单对象”之间的区别是什么,以及“简单->基本方法调用”是什么。还有,为什么
尺寸?此外,我认为有必要提供一些示例代码来说明构造函数调用的实际问题
关于这个设计,我现在可以告诉你的一件事是,在虚拟方法表中存储一个指向构造函数的指针,这让我感到奇怪。在我所知道的所有面向对象语言中,(C++、Java、C#)构造函数从来都不是虚拟的;它们看起来更像“静态”方法,用C语言来说,它们只是简单的按名称链接方法。这很好,因为每个类都有内置的、绝对确定的、不变的关于其基类是谁的知识
无论如何,链式构造函数调用应该是这样发生的:
void basemost_init( struct basemost* this, char* name )
{
this->class = &basemost_class;
this->name = name;
...
}
void intermediate_init( struct intermediate* this, char* name )
{
basemost_init( &this->base, name );
this->class = &intermediate_class;
...
}
void descendant_init( struct descendant* this, char* name )
{
intermediate_init( &this->base, name );
this->class = &descendant_class;
...
}
编辑(经过一些澄清)
如果你想让它在分配端看起来很酷,也许可以尝试这样的方法:(我不确定我对C语法的记忆有多好,所以请原谅任何小的错误。)
这样,您就不再需要尺寸了。另外,请注意,您可以按照需要传递尽可能多的构造函数参数,而不限于固定的、预定数量的参数(我认为这是非常重要的),而不必使用变量构造函数。
如果您承诺使用一致的命名,那么您也可以使用#define
宏为所有类实现相同的功能,这样每个构造函数的名称都可以计算为structname##u init
,但我不知道如何在C中的this
指针之后通过宏传递任意构造函数参数。无论如何,我宁愿避免使用宏,除非它们是绝对必要的,在这种情况下它们不是。super\u init
不能这样工作,它需要调用super的类,否则(正如您所发现的)直接超类构造函数最终会一遍又一遍地调用自己。因为每个类都知道自己的父类,所以它可以直接调用超类的init。例如,simple.init
将调用specific.init
,后者将依次调用constructed.init
,依此类推
如果你坚持要一个函数来为你做这件事,你必须给它一个类,这样它就可以(很简单)调用超类的构造函数。就是这种设计的一个例子。Python 3引入了一种更易于使用的super
,但它需要编译器的支持来找出要传递给底层函数的正确类。不太清楚struct\u class
的实现应该如何工作ass有自己的一套方法,它们的签名也不同。一个一刀切的结构类如何解决这个问题呢?你想要多重继承还是多重继承还不是很清楚。我的意思是多重继承而不是多重继承,我的错。我对这个问题做了一些编辑,hope it有帮助。我使用OOC手册中使用的方法,其思想是每个类都有一个指向对象使用的初始化器的指针。每个类初始化对象。大小允许我做:new(struct_class)->这将malloc实例的适当大小,然后对其调用init。“每个类都有一个指向对象使用的初始值设定项的指针”这是一个坏主意,而OOC是一本糟糕且误导的书。他们在类描述符中放入init
,这样他们就可以为new