用C++些文件拷貝程序遠(yuǎn)遠(yuǎn)比想象的要困難的多,和C#僅使用的File類和Directory類相比,直接操作windows api更加有趣。這個(gè)過程讓我體會(huì)到的不僅僅是api,更多是編寫程序這一個(gè)過程的本質(zhì)。
先和大家分享一下我的代碼,還請(qǐng)各位C++前輩們指教。
.h文件
#pragma once
#include
#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)
{
//獲取相對(duì)路徑
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;
//創(chuàng)建文件夾
Common::File::CreatePath(targetFilePath);
//創(chuàng)建新文件路徑
wstring newFileName = targetFilePath + L"" + Common::File::GetFileNameFromFilePath(fileName);
//復(fù)制文件
CopyFile(fileName.c_str(), newFileName.c_str(), true);
}
其實(shí)在之前的一篇blog中,我寫了一個(gè)遍歷文件目錄的函數(shù)( 文件夾遍歷代碼C++(win32平臺(tái))),在這個(gè)函數(shù)的參數(shù)列表中,考試,大提示有一個(gè)函數(shù)指針??荚?大意圖是通過這個(gè)函數(shù)指針,能夠處理遍歷到的文件。由于在C#中,可以通過delegate來聲明一個(gè)類似與函數(shù)指針的類型,然后通過該類型來定義一個(gè)對(duì)象來指向執(zhí)行方法的地址,所以我也想在C++中如法炮制。可是最后C++編譯器告訴我,這種寫法是錯(cuò)誤的。在C++中,函數(shù)指針指向的是一個(gè)靜態(tài)地址,如果我要將指針指向類實(shí)例的一個(gè)成員方法,這在C++中是不允許的(聽說boost中一個(gè)解決方法)。這讓我明白了C++和C#中相似的地方并不相同。不過這也給了我想象的空間:去想象C#編譯器是如何用delegate去實(shí)現(xiàn)函數(shù)指針的功能的或者說它們之間有本質(zhì)的區(qū)別。
另外一個(gè)很重要的體驗(yàn)是,C++的開發(fā)環(huán)境遠(yuǎn)沒有C#那么智能(VS2008),特別是智能感知那一塊。這讓我在最開始些代碼的時(shí)候總是感到不穩(wěn),像一個(gè)醉漢走路,搖搖晃晃的。后來我發(fā)現(xiàn),這種擔(dān)心源于我自己對(duì)C++編譯器的類型檢查特性沒有充分的認(rèn)識(shí)。我們可以放心大膽的去寫代碼,然后compile,如果有問題,編譯器會(huì)很精確的告訴你。這種認(rèn)識(shí)對(duì)重構(gòu)代碼很有幫助。在之后的工作中,對(duì)于那些C#代碼,我都感很放心的去重構(gòu),因?yàn)榫幾g器會(huì)告訴我問題出在什么地方。也就是基于這種認(rèn)識(shí),在寫C#代碼的時(shí)候,盡量避免使用像datatable之類的類型,因?yàn)榫幾g器不能對(duì)其中的數(shù)據(jù)類型進(jìn)行類型檢查,這樣我們也就享受不到編譯器類型檢查這項(xiàng)功能帶來的實(shí)惠。
還有就是單元測(cè)試的工作方式。最開始寫C++代碼,每寫一行代碼我都不敢確定它的輸出結(jié)果是正確的或是什么樣子。為了解決這個(gè)問題,我基本上為每個(gè)函數(shù)編寫專門的調(diào)試代碼。后來我發(fā)現(xiàn)這是一種不錯(cuò)的工作方式,效率很高。這種工作方式就是在.net世界中的單元測(cè)試呀。
先和大家分享一下我的代碼,還請(qǐng)各位C++前輩們指教。
.h文件
#pragma once
#include
#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)
{
//獲取相對(duì)路徑
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;
//創(chuàng)建文件夾
Common::File::CreatePath(targetFilePath);
//創(chuàng)建新文件路徑
wstring newFileName = targetFilePath + L"" + Common::File::GetFileNameFromFilePath(fileName);
//復(fù)制文件
CopyFile(fileName.c_str(), newFileName.c_str(), true);
}
其實(shí)在之前的一篇blog中,我寫了一個(gè)遍歷文件目錄的函數(shù)( 文件夾遍歷代碼C++(win32平臺(tái))),在這個(gè)函數(shù)的參數(shù)列表中,考試,大提示有一個(gè)函數(shù)指針??荚?大意圖是通過這個(gè)函數(shù)指針,能夠處理遍歷到的文件。由于在C#中,可以通過delegate來聲明一個(gè)類似與函數(shù)指針的類型,然后通過該類型來定義一個(gè)對(duì)象來指向執(zhí)行方法的地址,所以我也想在C++中如法炮制。可是最后C++編譯器告訴我,這種寫法是錯(cuò)誤的。在C++中,函數(shù)指針指向的是一個(gè)靜態(tài)地址,如果我要將指針指向類實(shí)例的一個(gè)成員方法,這在C++中是不允許的(聽說boost中一個(gè)解決方法)。這讓我明白了C++和C#中相似的地方并不相同。不過這也給了我想象的空間:去想象C#編譯器是如何用delegate去實(shí)現(xiàn)函數(shù)指針的功能的或者說它們之間有本質(zhì)的區(qū)別。
另外一個(gè)很重要的體驗(yàn)是,C++的開發(fā)環(huán)境遠(yuǎn)沒有C#那么智能(VS2008),特別是智能感知那一塊。這讓我在最開始些代碼的時(shí)候總是感到不穩(wěn),像一個(gè)醉漢走路,搖搖晃晃的。后來我發(fā)現(xiàn),這種擔(dān)心源于我自己對(duì)C++編譯器的類型檢查特性沒有充分的認(rèn)識(shí)。我們可以放心大膽的去寫代碼,然后compile,如果有問題,編譯器會(huì)很精確的告訴你。這種認(rèn)識(shí)對(duì)重構(gòu)代碼很有幫助。在之后的工作中,對(duì)于那些C#代碼,我都感很放心的去重構(gòu),因?yàn)榫幾g器會(huì)告訴我問題出在什么地方。也就是基于這種認(rèn)識(shí),在寫C#代碼的時(shí)候,盡量避免使用像datatable之類的類型,因?yàn)榫幾g器不能對(duì)其中的數(shù)據(jù)類型進(jìn)行類型檢查,這樣我們也就享受不到編譯器類型檢查這項(xiàng)功能帶來的實(shí)惠。
還有就是單元測(cè)試的工作方式。最開始寫C++代碼,每寫一行代碼我都不敢確定它的輸出結(jié)果是正確的或是什么樣子。為了解決這個(gè)問題,我基本上為每個(gè)函數(shù)編寫專門的調(diào)試代碼。后來我發(fā)現(xiàn)這是一種不錯(cuò)的工作方式,效率很高。這種工作方式就是在.net世界中的單元測(cè)試呀。