(靠~招式快用完了,沒神秘感了)
事情是這樣的
我們遇到一個問題,得在程式內去更改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)我本人就不推崇,很多缺點(本文就帶到其一),有空再另文分析。
沒有留言:
張貼留言