1. 程式人生 > >一個針對接口設計的例子想到的

一個針對接口設計的例子想到的

c++ 針對 規範 情況 出錯 virtual 變量 cnblogs 做了

一個簡單的例子,關於一個門的簡單設計:

 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語言晦澀難懂,還容易出錯。

可見,由非面向對象的語言來實現面向對象功能實在是一件麻煩的事。

充分發揮編譯器的智能,可以寫出來更優秀的代碼。

一個針對接口設計的例子想到的