2012-11-11 65 views
2

我有以下基於組件的架構。如何從特定組件的更新功能中跳出正在更新組件的管理器循環?中斷代碼執行

組件

class Component 
{ 
    virtual void Update() = 0; 
}; 

經理

class Manager 
{ 
    vector<Component*> List; 
    void Add(Component* cpnt) 
    { 
     List.push_back(cpnt); 
    } 
    void Loop() 
    { 
     while(1) 
     { 
      for (auto i = List.begin(); i != List.end(); i++) 
       i->Update(); 
     } 
    } 
}; 

class Example : public Component 
{ 
    void Update() 
    { 
     // want to break out of mgr's while loop from here 
    } 
}; 

int main() 
{ 
    Manager mgr; 
    mgr.Add(new Example()); 
    mrg.Loop(); 
} 

(請注意,我忽略accesors在本例中爲簡單起見。)

+1

+1僅包含代碼的相關部分:) – Alex

回答

3

您可以從Update中拋出一個異常,並從循環中捕獲它,或者從循環中捕獲它,具體取決於返回值Update

你選擇哪一個取決於邏輯。如果退出循環是邏輯錯誤的結果,請使用異常。

如果它是邏輯的一部分,請使用返回。

+0

+1我希望更多的人會遵循最後兩句中的使用模式。 – WhozCraig

+1

謝謝,它是經理結束某個時間的邏輯的一部分。 – danijar

1

您可以Update返回值,在此基礎上您可能不想繼續循環。

您也可以使用例外。

-1

如果你可以改變Update,讓它返回一個bool告訴管理員它是否應該中斷。

while(1) 
    { 
     for (auto i = List.begin(); i != List.end(); i++) 
      if(!i->Update()) 
       goto end_loop; 
    } 
    end_loop: 

我用goto退出外循環,可以使用一個變量來使雙break如果你害怕goto

如果Loop中沒有其他內容可以執行,您可以(也應該)使用return

+1

仇恨者會討厭。 – Alex

+0

在更新函數中執行循環遠不止於此。基本上所有組件的邏輯都放在那裏。 – danijar

+1

@sharethis我在'while'後面討論'Manager :: Loop'。如果在while的右括號之後有一些代碼,則需要打破它。否則,你只能'返回;' – Alex

1

設置Update()返回一個代碼,指示是否停止,並檢查Manager循環中的代碼。或者拋出一個異常,這會更像C++,如果發生並不是經常發生的事情。

也就是說,要麼改變virtual void Update()virtual bool Update()或相似,具有以下Manager循環:

bool ok = true; 
while(ok) 
    for (auto i = List.begin(); i != List.end() && ok; i++) 
     ok = i->Update(); 

或者使Update()拋出一個異常:

void Update() 
{ 
    do stuff; 
    if(bad) throw SomeException(); 
} 

,敷Manager環在try/catch條款。

+0

你能解釋拋出異常嗎? – danijar

+0

如果你對'C++'異常一無所知,你可以在這裏瞭解它們(http://www.cplusplus.com/doc/tutorial/exceptions/) – amaurea

+0

不要在流量控制中使用異常。 – Alex