天天看點

C++函數内的批量處理

在用C++寫一個函數的時候,發現其中需要對很多個類似的變量進行類似的處理,如:

if (map.exists(var1.getName()) {  

    process(map.get(var1.getName()));  

程式中有很多個類似var的變量,而且都不在數組中。是以隻能一個個的使用上述語句進行處理。為了簡體代碼,也為了代碼的複用性,這裡想到了4種辦法,各有優劣。

1. 定義私有成員函數

  定義一個private的成員函數來處理。由于處理語句較少,為了提高處理效率,這個私有成員函數可以定義成inline的。例:

// @(#) MyClass.h  

class MyClass ...{  

    // ......  

private:  

    void handle(Type& var) ...{  

        if (map.exists(var.getName()) ...{  

            process(map.get(var.getName());  

        }  

    }  

};  

// @(#) MyClass.cpp  

void MyClass::Handling(void) ...{  

    handle(var1);  

    handle(var2);  

    // ...  

    handle(varn);  

}  

這是最常見的做法。但使用這個方法,如果定義成inline函數,則代碼會出現在頭檔案中,沒能很好的隐藏。如果不定義為inline函數,對效率又有影響。當然,優點也是顯而易見的,這個方法最容易想到,這是其一。其二,使用這個方法,代碼看起來會比較整潔。

2. 定義目前編譯單元内的全局函數

  為了克服第1種方法中的缺點,不難想到——如果将這個處理函數定義在MyClass.cpp中,不作為成員函數定義。問題不是就解決了嗎?為了在其它代碼檔案中隐藏這個函數(不讓其它cpp檔案中的函數調用它),還可以将其申明為static的。于是:

inline static void handle(Type& var) ...{  

    if (map.exists(var.getName()) ...{  

        process(map.get(var.getName());  

    ::handle(var1);  

    ::handle(var2);  

    ::handle(varn);  

這樣的确很好的解決了隐藏代碼的問題,同時也解決了效率的問題。但是,handle函數是一個僅僅用于MyClass::Handling中的臨時函數,卻定義在MyClass::Handling之外。如果有一天不再需要MyClass::Handling而将它删除的時候,很容易忘記删除handle函數的。這些代碼中就會留下垃圾代碼(即沒有任何作用的代碼)了。

  于是,又想到了另一個方案——

3. 在函數中定義宏并在使用後取消定義

  在函數體内使用#define定義一個臨時的宏進行上述處理。,并在處理所有變量之後,函數結束前,使用#undefine取消對該宏的定義。這樣,相當于由編譯器展開宏來實作了這些語句的錄入。例:

    // .....  

#define __HANDLE(VAR)   

    if (map.Exists(VAR.getName())   

    Process(map.get(VAR.getName());  

    __HANDLE(var1);  

    __HANDLE(var2);  

    __HANDLE(varn);  

#undef __HANDLE  

這樣雖然把代碼搞得有點不太整潔,但也不失為一個解決方案,隻是——如果在别處也有定義__HANDLE宏,#undefine豈不是把那個宏取消掉了,會不會造成以後的代碼出問題呢?要是能在函數内定義函數就好了。可惜C++沒有提供在函數内定義函數的特性,倒是有個類似的東西——局部類。

4. 定義局部類

  局部類就是定義在函數内部的類。局部類和普通的類相似,但不能擁有靜态成員。局部類可以通路其外部函數中的靜态變量,但不能通路其普通變量。如果改用靜态類,代碼如下:

    class T ...{  

    public:  

        T(MapType& map) : m_Map(map) ...{}  

        void handle(Type& var) ...{  

            if (m_Map.exists(var.getName()) ...{  

                process(m_Map.get(var.getName());  

            }  

    private:  

        MapType& m_Map;  

    } t(map);  

    t.handle(var1);  

    t.handle(var2);  

    t.handle(varn);  

據說C++的局部類幾本上沒有什麼作用。實際看看上例,也會啞然失笑。上例隻是為了實作一個“局部函數”,定義就寫了一大堆。因為沒有做過仔細的測試,也不知道其效率如何。編譯時估計還得為這個局部類配置設定空間,實在有點得不償失。

小結

  隻不過為了在一個函數中進行簡單的批量處理,一不小心就搞了這麼些東西出來。至于實際程式設計過程中使用哪種方法來進行批處理,就看各位自己的喜好了。

本文轉自邊城__ 51CTO部落格,原文連結:http://blog.51cto.com/jamesfancy/843214,如需轉載請自行聯系原作者

繼續閱讀