2013-09-05 65 views
0

如果我希望只起函數的第二次調用一個函數運行一段代碼,執行一段代碼開始

問題:

  1. 這樣做有什麼不對嗎?

  2. 我該怎麼做到這一點?是使用靜態變量來做到這一點的好主意?

+2

一個普通的靜態是好的,除非你的函數是從多個線程中調用的。 – Peter

回答

1

有兩個答案這個問題,這取決於您是否需要處理多線程序列化與否。

無螺紋:

void doSomething() { 
    static bool firstTime = true; 
    if (firstTime) { 
     // do code specific to first pass 
     firstTime = false; 
    } else { 
     // do code specific to 2nd+ pass 
    } 
    // do any code that is common 
} 

隨着線程: 我會寫一般的樣板,但是這個代碼是系統特定的(需要原子compareAndSet的一些變體)。

void doSomethingThreadSafe() { 
    static volatile atomic<int> passState = 0; 

    do { 
     if (passState == 2) { 
      //perform pass 2+ code 
      break; 
     } else 
     if (passState.compareAndSet(0,1)) { // if passState==0 set passState=1 return true else return false 
      //perform pass 1 initialization code 
      passState = 2; 
      break; 
     } else { 
      //loser in setup collision, delay (wait for init code to finish) then retry 
      sleep(1); 
     } 
    } while(1); 

    //perform code common to all passes 
} 
-1

添加一個全球計數器。 例如: -

static int counter = 0;

public void testFunc(){ 

    if(counter==1){ 

     ........ 
     <Execute the functionality> 
     ........ 

    } 
    counter++; 

} 
+0

這不是唯一的方法,再加上它讓櫃檯在那裏讓別人篡改。計數器可以是函數內的一個「靜態」變量。哦,問題是標記爲C++。 – juanchopanza

+0

然後做它的C++方式:) – Arun

+2

在很多方面是錯誤的:1)公共虛擬? 2)不處理多線程問題,3)僅在第二次調用時執行,這不是OP的請求,4)計數器最終會翻轉,5)爲什麼初始化計數器的時間是1而不是0?初始化爲1很難說它計算的是什麼。 6)用'counter'這樣的名字來污染全局命名空間是個壞主意。 – Speed8ump

1
  1. 多線程將是一個問題。爲防止這種情況發生,如果需要,您可能需要類似mutex的東西。

  2. 像這樣:

    void someFunction() 
    { 
        static bool firstRun = true; 
        if (!firstRun) 
        { 
         // code to execute from the second time onwards 
        } 
        else 
        { 
         firstRun = false; 
        } 
        // other code 
    } 
    
+1

移動'firstRun = false;'進入條件以節省少量的CPU時間。 (編輯:我的意思是作爲其他部分) – Speed8ump

+0

對不起,我不清楚,我的意思是一個別的。這樣它只能運行第一遍。 – Speed8ump

+0

@ Speed8ump好的,很酷。是的,這可能會稍微好一點(儘管我會說可讀性)。 – Dukeling