2012-11-11 137 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