C++基礎(chǔ):C++文件拷貝代碼

字號(hào):

用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è)試呀。