二、使用构造Composition代替继承Inheritance
如果现在有两个接口Iface1, Iface2. 每个接口对应一个数据类型(结构体)。
struct Dface1; struct Dface2; struct Iface1{ void(*init)(struct Dface1* data); void(*dosomething)(struct Dface1* data); }; struct Iface2{ void(*init)(struct Dface2* data); void(*dosomething)(struct Dface2* data); };
如果有一个类ClassAnother需要实现接口Iface1和Iface2:
struct ClassAnother{ struct Iface1* i_face1; struct Iface2* i_face2; struct Dface1 d_face1; // 这里不使用指针 struct Dface2 d_face2; // 这里不使用指针 };
为ClassAnother创建接口Iface1和Iface2的实例:
struct Iface1 i_face1_for_ClassAnother = { face1_init_for_ClassAnother, face1_dosomething_for_ClassAnother, }; struct Iface2 i_face2_for_ClassAnother = { face2_init_for_ClassAnother, face2_dosomething_for_ClassAnother, };
为ClassAnother写一个初始化函数:
ClassAnother_init(struct ClassAnother* c) { c->i_face1 = &i_face1_for_ClassAnother; //注意呀!要先初始化接口指针! c->i_face2 = &i_face2_for_ClassAnother; //第二个接口指针 c->i_face1->init(&c->d_face1); c->i_face2->init(&c->d_face2); }
实例化ClassAnother的一个对象:
struct ClassAnother ObjectAnother; ClassAnother_init(&ObjectAnother);
调用个函数试试:)
ObjectAnother->i_face1->dosomething(&ObjectAnother.d_face1);
再试试face2的:
ObjectAnother->i_face2->dosomething(&ObjectAnother.d_face2);
小结:
代码继续清爽。使用Composition还是清晰一点呀,要是以继承为主,就要带上很多ctor,dtor,甚至父类指针这些俺觉得都属于"c语言偏僻技巧"。俺想要是维护代码的人看了父类指针不断往上指,估计还真是要砍人了。
三、 不愿意出现的继承Composition
在很多C面向对象的文章中都提到了如何去实现继承。用struct去封装类成员吧,继承一次套一层?用宏去封装吧,最后宏套宏的?俺认为这些都属于"C语言偏僻技巧",这是另外一个不建议在C语言里主推继承的原因。
但是有些类的确又避免不了继承的出现,那就只好老老实实的一个成员一个成员写上去了。
struct Dface; struct Iface{ void(*init)(struct Dface* data); void(*dosomething)(struct Dface* data); }; struct Imore{ void(*init)(struct Dmore* data); void(*domore)(struct Dmore* data); };
定义基类:
struct ClassBase{ struct Iface* i_face; struct Dface d_face; };
定义子类:
struct ClassDerived{ struct Iface* i_face; struct Imore* i_more; struct Dface d_face; struct Dmore d_more; int w,h,y; };
父类构造函数:
void ClassBase_init(struct ClassBase* o) { o->i_face = &i_face_for_ClassBase; o->i_face->init(&o->d_face); }
子类构造函数:
void ClassDerived_init(struct ClassDerived* o) { ClassBase_init((struct ClassBase*)o); o->i_more = &i_more_for_ClassDerived; o->i_more->init(&o->d_more); }
实例化ClassDerived:
struct ClassDerived Object; ClassDerived_init(&Object);
调用个函数试试:) ~~
Object.i_face->dosomething((struct Dface*)&Object.d_face);
小结:
其实上边继承的办法还算清晰。再加多几层也没有关系,但是在代码层来看就很难看出继承的关系了,因为没有用struct也没有用宏进行封装。尽量避免吧。
参考:
1.博客文章:《我所偏爱的 C 语言面向对象编程范式》 云风的BLOG
2.程序代码:《LW_OOPC》 http://sourceforge.net/projects/lwoopc/
3.图书:《Object-oriented Programming with ANSI-C》
4.图书:《Python源码剖析》