[英]How to make C++ function return to its first line?
所以我在win32 C ++控制台应用程序中有一个函数,例如:
void initFFmpeg(string url ,string container, int w, int h, int fps)
{// we want to return here
encoder.SetConstants(fps, videoWidth, videoHeight, audioSampleRate);
// ... more code...
if (encoder.InitUrl(container, url, outputUserName) == -1)
{
// ...some more code...
// Now we want to return
}
// ... more code...
}
如何启用此类退货?
通常,您可以表达一个自然的循环( while
, for
或do...while
),否则想要任意跳转到函数顶部的感觉就像是糟糕的设计。
做您想说的最简单的方法是使用goto
:
void function()
{
top:
// ...
goto top;
// ...
}
编辑:完全伪造do..while
示例。
有些人不喜欢goto
这个词,他们会坚持将所有内容永久循环并使用continue
,但这只是另一个名字的goto。
void function()
{
for (;;)
{
// ...
continue;
// ...
break;
}
}
看来您要尝试的是继续尝试各种格式,直到ffmpeg成功打开该URL。 这可能是您想要做的(并且IMHO清洁器比goto
清洁器)。
void initFFmpeg(string url ,string container, int w, int h, int fps)
{
do {
encoder.SetConstants(fps, videoWidth, videoHeight, audioSampleRate);
// ... more code...
// use whatever condition indicates success
if (encoder.InitUrl(container, url, outputUserName) != -1)
break;
// ...some more code...
} while (true) ;
// ... more code...
}
您可以使用while循环或for循环多次遍历该函数。 应该叫多少次? 如果只是两次,则可能只需调用该函数两次,但除此之外,您还需要使用某种循环。
您也可以使用goto,但是循环可能会更好。
这是非常糟糕的c + +风格,但也许goto
?
给定您的代码,...
void initFFmpeg(string url ,string container, int w, int h, int fps)
{// we want to return here
encoder.SetConstants(fps, videoWidth, videoHeight, audioSampleRate);
// ... more code...
if (encoder.InitUrl(container, url, outputUserName) == -1)
{
// ...some more code...
// Now we want to return
}
// ... more code here...
}
...并且假设您确实确实想在InitUrl
失败时再次调用SetConstants
,表达您想要的“返回”的自然方法是使用C ++ return
语句,例如...
bool initEncoder(
string const& url,
string const& container,
string const& userName
)
{
encoder.SetConstants( fps, videoWidth, videoHeight, audioSampleRate );
// ... more code...
if( encoder.InitUrl( container, url, userName ) == -1 )
{
// ...some more code...
// Now we want to return, so:
return false;
}
return true;
}
void initFFmpeg( string const& url ,string const& container, int w, int h, int fps )
{
while( !initEncoder( url, container, outputUserName ) )
{}
// ... more code here...
}
您也可以例外处理。 这可能更清楚,但效率可能会降低。 假设重试是常见的。
或者,您可以在for(;;)
循环中使用continue
。 我不喜欢continue
,并且它用处不大(至少正如几年前Google Code Search报道的那样)。 但这可能只是医生根据同事对什么是好的代码的信念而下令的。
注意:从技术上讲,也可以使用goto
,但是最好不要使用机器生成的代码。 有关此背景的信息,请参阅Dijkstra最初的1968年文章“去认为有害” 。 尽管到2010年已经有42年历史了,但它仍然是一颗宝石-最好不要忘记 。
使用循环。 使用do {} while表单是因为您显然希望所有内容至少执行一次。
void initFFmpeg(string url ,string container, int w, int h, int fps)
{
bool success = false;
do
{
encoder.SetConstants(fps, videoWidth, videoHeight, audioSampleRate);
// ... more code...
success = (encoder.InitUrl(container, url, outputUserName) != -1);
if(!success)
{
// ... more code ...
}
// ... more code ...
} while(!success);
}
循环或转到的替代方法是递归。
void initFFmpeg(string url ,string container, int w, int h, int fps)
{
encoder.SetConstants(fps, videoWidth, videoHeight, audioSampleRate);
// ... more code...
if (encoder.InitUrl(container, url, outputUserName) == -1)
{
initFFmpeg(url, container, w, h, fps);
return;
}
// ... more code...
}
但是,与其他一些语言相比,C ++中的递归没有那么习惯。 C ++编译器往往不会优化尾调用,而深度递归会导致难以调试堆栈溢出。
如果我确定不能重复多次,则可以在这里使用递归。 否则,我可能只会使用* shiver * goto
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.