故事是這樣的,wendy老鳥寫了兩個 class GamePlayer & IResourceLoader, IResourceLoader有一些基本resource check跟 load跟debug的功能,而我們這小咖的任務是base在 IResourceLoader的架構,作一個特製的PolygonLoader(),如下。
class PolygonLoader : public IResourceLoader { public: void load(GamePlayer& p) { p.PolygunRESID = 128; // Compiler error!! } };問題來了,PolygonLoader不是GamePlayer的朋友,上面error怎麼辦?
簡單的說法: wendy 你的class有bug,你看我這邊有error耶 ,應該把這member搬到public吧 !(瞬殺)
還好的說法: wendy 可不可以你麻煩幫忙在IResourceLoader修改,加一個GetResID(){return pGamePlayer.PolygunRESID}; or SetResID() 之類的東西呢? (但是用到IResourceLoader的部門可能都會面臨重新compiler module)。
其實透過inner class的技巧 wendy已經在GamePlayer為我們的需求開了條路。
class GamePlayer{ public: enum SpecialTypeClass { Mage = 0, Paladin , War , Shaman , Thief, TalentNum }; friend class IResourceLoader; template在implement PolygonLoader時就可以透過實際implement PrivateAccessorclass PrivateAccessor; //GamePlayer(int classType); GamePlayer(SpecialTypeClass seed); void Attack(); GamePlayer();GamePlayer& operator = (const GamePlayer&); private: GamePlayer(const GamePlayer&); static const int NumTurns = 5; int PolygunRESID; SpecialTypeClass Talent; int scores[NumTurns]; };
/////PolygonLoader.h////// class PolygonLoader : public IResourceLoader { public: void load(GamePlayer& player) ; }; template<> class GamePlayer::PrivateAccessor比較覺得可以討論的部分是,難道當Create一個class的時候,開個後門(PrivateAccess)是一個良好的習慣嗎?有沒有其他更好的作法可以盡量維持原架構不變,達到擴充的目的。{ public: static int& ResID(GamePlayer& player){ return player.PolygunRESID; } }; /////PolygonLoader.cpp////// typedef GamePlayer::PrivateAccessor Accessor; void PolygonLoader::load(GamePlayer& player){ //modify private member here! Accessor::ResID(player) = 1234; };
Reference link: 還是簡單點好
“但是用到IResourceLoader的部門可能都會面臨重新compiler module”
回覆刪除我覺得這句話是關鍵
"難道當Create一個class的時候,開個後門(PrivateAccess)是一個良好的習慣嗎?"
所以我覺得是否定的
除了發現inner class跟private member的技巧以外,會提這篇是這個案例提供了我們"需求"。基本上我不是很喜歡這篇提到的設計。但是如何設計一個讓別人好用,擴充性強又不需要常修改的class,腦子裡沒有更好的作法。
回覆刪除欠的意思是不是覺得也不必這麼刻意避開修正IResourceLoader?有需求就應該改。
ps: 這篇對我還有個暗示,trace 別人的code debug時別太鐵齒,private member還是有可能因為某個public 的 inner class被其他人更動到的 XD
我的意思是 “但是用到IResourceLoader的部門可能都會面臨重新compiler module” 是一個很好的出發點,並且是這個範例所要解決的真正問題。
回覆刪除