用C++些檔案拷貝程式遠遠比我想象的要困難的多,和C#僅使用的File類和Directory類相比,直接操作windows api更加有趣。這個過程讓我體會到的不僅僅是api,更多是編寫程式這一個過程的本質。先和大家分享一下My Code,還請各位C++前輩們指教。.h檔案
- #pragma once
- #include <string>
- #include "file.h"
- using namespace std;
- namespace Common
- {
- namespace File
- {
- class SyncFolder : public Common::File::FileClass
- {
- private:
- wstring m_sourceDirectory;
- wstring m_targetDirectory;
- const wstring * m_ext;
- const bool * m_reverseExt;
- protected:
- void FileMethod(const wstring&);
- public:
- SyncFolder(const wstring &sourceDirectory, const wstring &targetDirectory,const wstring &ext, bool reverseExt):FileClass(),
- m_sourceDirectory(Common::File::GetSecurePath(sourceDirectory)),m_targetDirectory(Common::File::GetSecurePath(targetDirectory))
- {
- m_ext = new wstring(ext);
- m_reverseExt = new bool(reverseExt);
- }
- ~SyncFolder(void)
- {
- delete m_ext;
- delete m_reverseExt;
- }
- void Exec();
- };
- }
- }
.cpp檔案
- #include "StdAfx.h"
- #include "SyncFolder.h"
- #include "File.h"
- void Common::File::SyncFolder::Exec()
- {
- ReadFiles(m_sourceDirectory, *m_ext);
- }
- void Common::File::SyncFolder::FileMethod(const wstring& fileName)
- {
- //擷取相對路徑
- wstring offsetPath =
- Common::File::GetRelativePath(m_sourceDirectory,
- Common::File::GetPathFromFilePath(fileName));
- //擷取新路徑
- wstring targetFilePath;
- if(offsetPath.empty())
- targetFilePath = m_targetDirectory;
- else
- targetFilePath = m_targetDirectory + L"//" + offsetPath;
- //建立檔案夾
- Common::File::CreatePath(targetFilePath);
- //建立新檔案路徑
- wstring newFileName = targetFilePath + L"//" + Common::File::GetFileNameFromFilePath(fileName);
- //複製檔案
- CopyFile(fileName.c_str(), newFileName.c_str(), true);
- }
其實在之前的一篇blog中,我寫了一個遍曆檔案目錄的函數( 檔案夾遍曆代碼C++(win32平台)),在這個函數的參數列表中,有一個函數指標。我的意圖是通過這個函數指標,能夠處理遍曆到的檔案。由於在C#中,可以通過delegate來聲明一個類似與函數指標的類型,然後通過該類型來定義一個對象來指向執行方法的地址,所以我也想在C++中如法炮製。可是最後C++編譯器告訴我,這種寫法是錯誤的。在C++中,函數指標指向的是一個靜態地址,如果我要將指標指向類執行個體的一個成員方法,這在C++中是不允許的(聽說boost中一個解決方案)。這讓我明白了C++和C#中相似的地方並不相同。不過這也給了我想象的空間:去想象C#編譯器是如何用delegate去實現函數指標的功能的或者說它們之間有本質的區別。另外一個很重要的體驗是,C++的開發環境遠沒有C#那麼智能(VS2008),特別是智能感知那一塊。這讓我在最開始些代碼的時候總是感到不穩,像一個醉漢走路,搖搖晃晃的。後來我發現,這種擔心源於我自己對C++編譯器的類型檢查特性沒有充分的認識。我們可以放心大膽的去寫代碼,然後compile,如果有問題,編譯器會很精確的告訴你。這種認識對重構代碼很有協助。在之後的工作中,對於那些C#代碼,我都感很放心的去重構,因為編譯器會告訴我問題出在什麼地方。也就是基於這種認識,在寫C#代碼的時候,盡量避免使用像datatable之類的類型,因為編譯器不能對其中的資料類型進行類型檢查,這樣我們也就享受不到編譯器類型檢查這項功能帶來的實惠。還有就是單元測試的工作方式。最開始寫C++代碼,每寫一行代碼我都不敢確定它的輸出結果是正確的或是什麼樣子。為瞭解決這個問題,我基本上為每個函數編寫專門的調試代碼。後來我發現這是一種不錯的工作方式,效率很高。這種工作方式就是在.net世界中的單元測試呀。總之,C++的學習讓我受益匪淺。希望能夠和大家多多交流。