一個針對接口設計的例子想到的
阿新 • • 發佈:2017-10-07
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 ILight2 { 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語言晦澀難懂,還容易出錯。
可見,由非面向對象的語言來實現面向對象功能實在是一件麻煩的事。
充分發揮編譯器的智能,可以寫出來更優秀的代碼。
一個針對接口設計的例子想到的