C++中回調(diào)的實(shí)現(xiàn)

C++中使用class語法實(shí)現(xiàn)回調(diào)
(當(dāng)然,椒楣,舊式的C函數(shù)指針回調(diào)也是支持的)

比如给郊,有人提供一個(gè)類庫 AfCopyFile,能夠提供文件拷貝的功能撒顿,而且能通知用戶當(dāng)前的進(jìn)度丑罪。。凤壁。

int DoCopy(const char* source,
const char* dst,
AfCopyFileListener* listener);

用戶只需要自己實(shí)現(xiàn)一個(gè)AfCopyFileListener對(duì)象吩屹,傳給這個(gè)函數(shù)就行。拧抖。煤搜。

class MainJob : public AfCopyFileListener{
int OnCopyProgress(long long total,
long long transfered){
    }
}

把Listener對(duì)象傳過去

AfCopyFile af;
af.DoCopy(source, dst, this); 

回調(diào)機(jī)制的缺點(diǎn):

無論是C語言的回調(diào)函數(shù),還是C++里的Listener唧席,都有一個(gè)共同的缺點(diǎn):

它使代碼邏輯變得難以閱讀擦盾。嘲驾。
我們應(yīng)盡量避免使用回調(diào)機(jī)制,最好采用單向的函數(shù)調(diào)用迹卢。

示例代碼:

AfCopyFile.h


#ifndef _AF_COPY_FILE_H
#define _AF_COPY_FILE_H

class AfCopyFile
{
public:
    // 作為內(nèi)部類
    class Listener
    {
    public:
        virtual int OnCopyProgress(long long total, long long transfered) = 0;
    };

public:
    int DoCopy(const char* source, const char* dst, Listener* listener);

};

#endif

AfCopyFile.cpp





#include <stdio.h>
#include <Windows.h>

#include "AfCopyFile.h"


// 將LARGE_INTTEGER類型轉(zhuǎn)成unsigned long long
inline unsigned long long translate(LARGE_INTEGER num)
{
    unsigned long long result = num.HighPart;
    result <<= 32;
    result += num.LowPart;
    return result;
}

// 回調(diào)函數(shù)
// 注:要求將此函數(shù)用關(guān)鍵字CALLBACK修飾(這是Windows API的要求)
static DWORD CALLBACK CopyProgress(  
                            LARGE_INTEGER TotalFileSize,
                            LARGE_INTEGER TotalBytesTransferred,
                            LARGE_INTEGER StreamSize,
                            LARGE_INTEGER StreamBytesTransferred,
                            DWORD dwStreamNumber,
                            DWORD dwCallbackReason,
                            HANDLE hSourceFile,
                            HANDLE hDestinationFile,
                            LPVOID lpData) // <- 這個(gè)就是上下文件對(duì)象
{
    // 計(jì)算百分比
    unsigned long long total = translate(TotalFileSize);
    unsigned long long copied =  translate(TotalBytesTransferred);

    // 打印進(jìn)度
    AfCopyFile::Listener* listener = (AfCopyFile::Listener*) lpData;
    listener->OnCopyProgress(total, copied);

    return PROGRESS_CONTINUE;
}

int AfCopyFile::DoCopy(const char* source, const char* dst, Listener* listener)
{
    BOOL ret = CopyFileEx(source, dst,
        &CopyProgress,  // 待回調(diào)的函數(shù)
        listener,       // 上下文對(duì)象
        NULL, 0);
    
    return ret ? 0 : -1;
}

main.cpp


#include <stdio.h>
#include <string.h>
#include "AfCopyFile.h"

class MainJob : public AfCopyFile::Listener
{
public:
    int DoJob()
    {
        strcpy(user, "shaofa");
        strcpy(source, "c:\\test\\2.rmvb" );
        strcpy(dst, "c:\\test\\2_copy.rmvb");

        AfCopyFile af;
        af.DoCopy(source, dst, this); // 將this傳過去
    
        return 0;
    }

    int OnCopyProgress(long long total, long long transfered)
    {
        // 打印進(jìn)度
        int percent = (int) ( (transfered * 100 / total) );     
        printf("[用戶: %s], %s -> %s : 進(jìn)度 %d %%\n", 
            user, source, dst, percent);

        return 0;
    }

private:
    char source[256];
    char dst[256];
    char user[64];
};

int main()
{
    MainJob job;
    job.DoJob();

    return 0;
}

??我的目標(biāo)是:someday辽故,即便你花錢看我的文章,也會(huì)覺得心滿意足


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末腐碱,一起剝皮案震驚了整個(gè)濱河市誊垢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌症见,老刑警劉巖喂走,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異谋作,居然都是意外死亡芋肠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門遵蚜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帖池,“玉大人,你說我怎么就攤上這事谬晕〉庠#” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵攒钳,是天一觀的道長(zhǎng)帮孔。 經(jīng)常有香客問我,道長(zhǎng)不撑,這世上最難降的妖魔是什么文兢? 我笑而不...
    開封第一講書人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮焕檬,結(jié)果婚禮上姆坚,老公的妹妹穿的比我還像新娘。我一直安慰自己实愚,他們只是感情好兼呵,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腊敲,像睡著了一般击喂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碰辅,一...
    開封第一講書人閱讀 50,050評(píng)論 1 291
  • 那天懂昂,我揣著相機(jī)與錄音,去河邊找鬼没宾。 笑死凌彬,一個(gè)胖子當(dāng)著我的面吹牛沸柔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播铲敛,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼褐澎,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了原探?” 一聲冷哼從身側(cè)響起乱凿,我...
    開封第一講書人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咽弦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胁出,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡型型,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了全蝶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闹蒜。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖抑淫,靈堂內(nèi)的尸體忽然破棺而出绷落,到底是詐尸還是另有隱情,我是刑警寧澤始苇,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布砌烁,位于F島的核電站,受9級(jí)特大地震影響催式,放射性物質(zhì)發(fā)生泄漏函喉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一荣月、第九天 我趴在偏房一處隱蔽的房頂上張望管呵。 院中可真熱鬧,春花似錦哺窄、人聲如沸捐下。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坷襟。三九已至,卻和暖如春咽白,著一層夾襖步出監(jiān)牢的瞬間啤握,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來泰國打工晶框, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留排抬,地道東北人懂从。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蹲蒲,于是被迫代替她去往敵國和親番甩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容