一个针对接口设计的例子想到的

一个简单的例子,关于一个门的简单设计:

 1 class IDoor
 2 {
 3 public:
 4     virtual void open()=0;
 5     virtual void close()=0;
 6 };
 7 
 8 class CDoor : public IDoor
 9 {
10 public:
11     virtual void open(){};
12     virtual void close(){};
13 };

现在国庆节来了,门上面都会挂上各种彩灯,所以就需要一个可以发光的门的概念,要重用上面的门,可以这样设计:

 1 class ILight
 2 {
 3 public:
 4     virtual void light()=0;
 5 };
 6 
 7 class CLightDoor : public IDoor, public ILight
 8 {
 9     ILight* mLight;
10     IDoor* mDoor;
11 public:
12     CLightDoor(ILight* _light, IDoor* _door):mLight(_light),mDoor(_door){}
13     void open(){mDoor->open();}
14     void close(){mDoor->close();}
15     void light(){mLight->light();}
16 };

我们根本没写什么代码,只是按照c++的规范进行了接口继承,竟然可以达到这么高的灵活性。

再加上一些测试代码:

 1 class CLight : public ILight
 2 {
 3 public:
 4     void light()
 5     {
 6     }
 7 };
 8 
 9 void testLight(ILight* light)
10 {
11     light->light();
12 }
13 
14 void testDoor(IDoor* door)
15 {
16     door->open();
17 }
18 
19 CLight light;
20 CDoor door;
21 CLightDoor lightDoor(&light, &door);
22 testLight(&lightDoor);
23 testDoor(&lightDoor);

 

而实际情况却是,虽然我们没有做什么事,但是c++编译器却帮助我们做了很多。

要达到一样的效果,采用c语言的做法大概是这样的:

 1 struct Door
 2 {
 3     void** Door_vtable;
 4 };
 5 void Door_open(Door* door){}
 6 void Door_close(Door* door){}
 7 void* g_Door_vtable[2]={Door_open, Door_close};
 8 
 9 struct Light
10 {
11     void** Light_vtable;
12 };
13 void Light_light(Light* light){}
14 void* g_Light_vtable[1]={Light_light};
15 
16 struct LightDoor
17 {
18     //相当于c++里面的继承
19     Door _door;
20     Light _light;
21     //成员变量
22     Door* mDoor;
23     Light* mLight;
24 };
25 void LightDoor_open(LightDoor* door){door->mDoor->open();}
26 void LightDoor_close(LightDoor* door){door->mDoor->close();}
27 void LightDoor_light(LightDoor* light){light->light->mLight->light();}
28 void* g_LightDoor_vtable0[2]={LightDoor_open, LightDoor_close};
29 void* g_LightDoor_vtable1[1]={LightDoor_light};
30 
31 Door door;
32 door.Door_vtable = g_Door_vtable;
33 Light light;
34 light.Light_vtable = g_Light_vtable;
35 
36 LightDoor lightDoor;
37 lightDoor._door.Door_vtable = g_LightDoor_vtable0;
38 lightDoor._light.Light_vtable = g_LightDoor_vtable1;
39 lightDoor.mDoor=&door;
40 lightDoor.mLight=&light;
41 
42 void testDoor(Door* door)
43 {
44     door->Door_vtable[0](door);
45 }
46 void testLight(Light* light)
47 {
48     light->Light_vtable[0](light);
49 }
50 
51 testDoor((void*)&lightDoor);
52 testLight(((void*)&lightDoor)+4);

上面加粗的代码在c++里面都没有对应的代码,而这都是由c++编译器自动生成的。而最后一行的加4偏移也是由编译器生成的。

同样的功能,c++条理清晰明白,c语言晦涩难懂,还容易出错。

可见,由非面向对象的语言来实现面向对象功能实在是一件麻烦的事。

充分发挥编译器的智能,可以写出来更优秀的代码。

posted on 2017-10-07 01:22  zhangshuliai  阅读(159)  评论(0编辑  收藏  举报