VC 函式只被呼叫一次

2022-07-26 08:24:12 字數 2781 閱讀 3291

如何保證某個函式只被呼叫一次

乙個函式caller會在其內部呼叫另外乙個函式callee,現在的情況是,caller可能會在多個地方被多次呼叫,而你希望callee只在第一次被呼叫時被呼叫一次。一般情況下,callee會是乙個對環境或者資源的初始化工作。

或許,從**結構的角度來講,你第乙個想到的是把callee從caller中拿出來,放到某個合適的地方做初始化,這是個不錯的方法,但相信我,在有些時候這並不是個有效的辦法:你可能無法找個那個「合適的地方」,你也可能找到了但因此而失去lazy initialization的好處~~~。

這裡,我只想對這個問題找個好點的方法。

第乙個方法很簡單,就是用個靜態的flag來判斷:

staticboolflag =false; if(!flag)

這個可以非常完美的工作,但是**感覺多了點,不夠簡潔。

而且每個後續呼叫都要有個取反和判斷操作,這對呼叫頻繁的操作的效能是有影響的。另外,即使影響不大,從程式設計師感受的角度來看,你也不希望有多餘的判斷~~~

哦,取反可以去掉:

staticboolflag =true; if(flag)

但是,判斷還是存在。

當然,我們還有第二種更簡潔的方法,假設callee的返回型別時int:

staticintdummy =callee(); // 1)

完了,利用靜態變數只初始化一次的特點就可以實現,簡潔,而且高效。

但是,這裡有個問題:如果callee的返回型別時void,那怎麼辦?你不能:

staticvoiddummy =callee(); staticintdummy =(int)callee(); staticintdummy =reinterpret_cast(callee());

因為void其實不是個型別,而是沒有型別。

即使你覺得自己很聰明,想出了下面這種方式:

booldummyfunc(void) staticbooldummy =dummyfunc(callee());

那也是不靈光的,不要以為callee返回void,把返回的void傳給dummyfunc的引數就可以了,因為void根本就不是個型別,根本沒有賦值,傳值這個概念~~~ 

幸虧c++中還有個叫逗號表示式的東西,說實話,c++用了7年多,這是我第一次發現逗號表示式這麼可愛:

逗號表示式會這個計算每個子表示式,並返回最後乙個子表示式的值 

於是,就有了這個解決方案:

staticbooldummy =(callee(), true); // 2)

也是同樣的簡潔、高效。

看來,直接用靜態變數初始化的方法是可以達到這個目的,而且會更好。

附:

我相信還會有其他方法來處理callee返回void的情況的,如果你知道,請不吝賜教! 

乙個函式caller會在其內部呼叫另外乙個函式callee,現在的情況是,caller可能會在多個地方被多次呼叫,而你希望callee只在第一次被呼叫時被呼叫一次。一般情況下,callee會是乙個對環境或者資源的初始化工作。

或許,從**結構的角度來講,你第乙個想到的是把callee從caller中拿出來,放到某個合適的地方做初始化,這是個不錯的方法,但相信我,在有些時候這並不是個有效的辦法:你可能無法找個那個「合適的地方」,你也可能找到了但因此而失去lazy initialization的好處~~~。

這裡,我只想對這個問題找個好點的方法。

第乙個方法很簡單,就是用個靜態的flag來判斷:

staticboolflag =false; if(!flag)

這個可以非常完美的工作,但是**感覺多了點,不夠簡潔。

而且每個後續呼叫都要有個取反和判斷操作,這對呼叫頻繁的操作的效能是有影響的。另外,即使影響不大,從程式設計師感受的角度來看,你也不希望有多餘的判斷~~~

哦,取反可以去掉:

staticboolflag =true; if(flag)

但是,判斷還是存在。

當然,我們還有第二種更簡潔的方法,假設callee的返回型別時int:

staticintdummy =callee(); // 1)

完了,利用靜態變數只初始化一次的特點就可以實現,簡潔,而且高效。

但是,這裡有個問題:如果callee的返回型別時void,那怎麼辦?你不能:

staticvoiddummy =callee(); staticintdummy =(int)callee(); staticintdummy =reinterpret_cast(callee());

因為void其實不是個型別,而是沒有型別。

即使你覺得自己很聰明,想出了下面這種方式:

booldummyfunc(void) staticbooldummy =dummyfunc(callee());

那也是不靈光的,不要以為callee返回void,把返回的void傳給dummyfunc的引數就可以了,因為void根本就不是個型別,根本沒有賦值,傳值這個概念~~~ 

幸虧c++中還有個叫逗號表示式的東西,說實話,c++用了7年多,這是我第一次發現逗號表示式這麼可愛:

逗號表示式會這個計算每個子表示式,並返回最後乙個子表示式的值 

於是,就有了這個解決方案:

staticbooldummy =(callee(), true); // 2)

也是同樣的簡潔、高效。

看來,直接用靜態變數初始化的方法是可以達到這個目的,而且會更好。

附:

我相信還會有其他方法來處理callee返回void的情況的,如果你知道,請不吝賜教! 

記一次實驗 複雜函式指標的呼叫

下午突然發憤決定搞定複雜指標的相關問題,看了幾篇大大們的文章後,感覺略有收穫。個人的總結 從非保留字讀起,如果有多個非保留字 如函式指標中的形參名,雖然這並沒有必要 從最左邊的讀起。此後,如果遇到右括號,則向左讀。如果遇到左括號,則向右讀,讀完所有括號後再按優先順序分析一次。我們來試一試,我會說的詳...

VC程式只執行一次例項

方法一 建立全域性互斥體,然後在程序啟動時檢查該互斥體是否已被建立 只需要在initinstance 中加入 方法二 乙個程式可以執行多個例項 程序 那我們如何讓它僅執行乙個例項呢?很簡單,使用 pragma編譯器指令在程序的位址空間內建立乙個 共享節 就可以 達到目的,這個 共享節 裡的資料為多個...

VC程式只執行一次例項

方法一 建立全域性互斥體,然後在程序啟動時檢查該互斥體是否已被建立 只需要在initinstance 中加入 方法二 一 個程式可以執行多個例項 程序 那我們如何讓它僅執行乙個例項呢?很簡單,使用 pragma編譯器指令在程序的位址空間內建立乙個 共享節 就可以 達到目的,這個 共享節 裡的資料為多...