(靠~招式快用完了,沒神秘感了)
事情是這樣的
我們遇到一個問題,得在程式內去更改current directory才能解決,所以在程式內加了幾行如List 1。
List 1 - Original
char oldCurrentDirectory[BUFSIZE]; GetCurrentDirectoryA(BUFSIZE, oldCurrentDirectory); SetCurrentDirectoryA(rootPath.c_str()); if(!m_hMod) { m_hMod = LoadLibraryA(m_sName.c_str()); } if(!m_hMod) { return NULL; } GETINSTANCEFUNC CreatePluginInstance = (GETINSTANCEFUNC) ( GetProcAddress( m_hMod, "CreatePluginInstance" ) ); if(!CreatePluginInstance) return NULL; _PluginInstance* pInstance = (CreatePluginInstance(rootPath.c_str())); if(!pInstance) return NULL; m_pInstanceVector.push_back(pInstance); return pInstance;
- Line 2: 先記下原本 的目錄以利還原。 (身為一個有道德的Programmer這是應該的)
- Line 3: 更改目前目錄成我們要的路徑。(簡單啦~)
這裡通常會遇到幾個內心的掙扎
- 管他的,反正沒還原搞不好也沒差,出問題再說,也搞不好不會找到我身上(這段code)。 <-- 破壞者
- 那我就copy paste在每個return的地方就好。 <-- 50%苦力 + 50% 破壞者
- 寫個class(如List 2)來解決好了。 <-- OO魔人 James
class StChangeCurrentDirectory { public: StChangeCurrentDirectory(const char *newPath) { GetCurrentDirectoryA(BUFSIZE, _oldCurrentDirectory); SetCurrentDirectoryA(newPath); } ~StChangeCurrentDirectory() { SetCurrentDirectoryA(_oldCurrentDirectory); } private: StChangeCurrentDirectory(const StChangeCurrentDirectory&); StChangeCurrentDirectory& operator=(const StChangeCurrentDirectory&); char _oldCurrentDirectory[BUFSIZE]; };這個class在constructor裡紀錄了目前目錄在它的member並更新的目前目錄。
在destructor裡還原目前目錄。所以程式可以改寫成List 3這樣。
List 3 - Using Stack-Based Class
StChangeCurrentDirectory changeToPluginRoot(rootPath.c_str()); if(!m_hMod) { m_hMod = LoadLibraryA(m_sName.c_str()); } if(!m_hMod) { return NULL; } GETINSTANCEFUNC CreatePluginInstance = (GETINSTANCEFUNC) ( GetProcAddress( m_hMod, "CreatePluginInstance" ) ); if(!CreatePluginInstance) return NULL; _PluginInstance* pInstance = (CreatePluginInstance(rootPath.c_str())); if(!pInstance) return NULL; m_pInstanceVector.push_back(pInstance); return pInstance;這個設計利用了C++ constructor/destructor 與 stack variable的特性。在changeToPluginRoot離開它的scope時自然會還原目前目錄的設定。
這樣的設計好處有
- 不會忘記還原。
- 可重複使用。
另外一方面,這段程式原先的寫法(指的是到處都有return)我本人就不推崇,很多缺點(本文就帶到其一),有空再另文分析。
沒有留言:
張貼留言