2010-08-01 64 views
0

有沒有什麼辦法只能調用一次函數?C++ - 基本功能問題

假設我有一些類

struct A { 

    void MainRoutine(Params) { 
     // Want to call other routine only once 
    } 

    void OtherRoutine(Params) { 
     // Do something that should be done only once and 
     // what depends on the params 
    } 
}; 

我想打電話給OtherRoutine僅在MainRoutine(我假設MainRoutine將被稱爲N次,我不能從構造函數中調用OtherRoutine一次,因爲它接受Params,當物體被構造時可能不可用。

基本上我想要做類似於

static bool called = false; 
if (!called) { 
    OtherRoutine(Params); 
    called = true; 
} 

但我希望有這樣做的更「漂亮」的方式...... (這可以寫在一行中)

使用boost::functionboost某些部分可能的東西,我不知道? :)

謝謝

+0

單行嗎?試試'static const bool dummy =(OtherRoutine(params),true);'而不是。 ;) – 2010-08-01 02:39:30

+0

@Georg嗯,我實際上正在考慮一些* OBVIOUS *行,但這也很酷) – 2010-08-01 02:41:01

回答

2

你也可以把只調用一次邏輯,你已經概述,裏面OtherRoutine,導致如果它之前已經執行它提前返回。

從邏輯上講,它幾乎相同。在風格上,它可能更好。

+0

而不是標準庫/增強有像'call_function_once'例程?我認爲這可能有點有用...無論如何,你的答案很好 – 2010-08-01 02:37:25

2

你是絕對正確的軌道上了。你應該把你的靜態'調用'變量放在你的結構中...... ahem:你應該把它變成一個類,把它變成私有的,並且確保在OtherRoutine中查詢靜態變量的狀態。 你不應該把它變得比它需要的更復雜。使用boost或其他任何簡單的機制只是矯枉過正。

2

你可以用boost :: function和bind來實現。假設你只想爲每個對象調用一次OtherRoutine,那麼

struct A { 
    A() { 
     Routine = boost::bind(&A::OtherRoutine, this); 
    } 

    boost::function<void()> Routine; 

private: 
    void MainRoutine() { 
     // Do stuff that should occur on every call 
    } 

    void OtherRoutine() { 
     Routine = boost::bind(&A::MainRoutine, this); 
     // Do stuff that should only occur once 
     MainRoutine(); 
    } 
}; 

A foo; 
foo.Routine(); // OtherRoutine is called 
foo.Routine(); // Now all subsequent calls will go to MainRoutine 
foo.Routine(); 

雖然我會建議做其他人說的話。雖然這看起來可能更「乾淨」,但與其他選擇相比,它過於複雜。

0

接近「可愛」的另一種方法是獲得一個靜態對象並從其構造函數中調用你的函數。喜歡的東西...

struct OneShotOtherRoutine 
    { 
     OneShotOtherRoutine(A a, Params params) 
     { 
     a.OtherRoutine(params); 
     } 
    }; 

    struct A 
    { 
     friend struct OneShotOtherRoutine; 
     public: 
     void MainRoutine(Params params) 
     { 
       static OneShotOtherRoutine(params); 
       // Main Routine code 
     } 
     private: 
     void OtherRoutine(Params params) 
     { 
      // Other routine code 
     } 
    }; 

你得的東西分裂,使每個實施能夠看到其他結構的聲明,但是這可能會做你想要什麼,假設它是可以接受的,當靜態初始化OtherRoutine被調用。