提问人:Luchian Grigore 提问时间:7/29/2011 更新时间:7/29/2011 访问量:1858
在 C++ 中返回时触发事件
Trigger event on return in C++
问:
我想在返回另一个函数之前执行某个函数。问题是有多个返回,我不想在每个返回之前复制粘贴我的调用。有没有更优雅的方法?
void f()
{
//do something
if ( blabla )
return;
//do something else
return;
//bla bla
}
我想在函数返回之前调用 g()。
答:
12赞
Andrey Agibalov
7/29/2011
#1
struct DoSomethingOnReturn {
~DoSomethingOnReturn() {
std::cout << "just before return" << std::endl;
}
};
...
void func() {
DoSomethingOnReturn a;
if(1 > 2) return;
}
评论
0赞
Lea Hayes
7/29/2011
@loki2302不错的伎俩,但对我来说似乎有点矫枉过正......我只是将任何复杂性包装在一个简单的函数调用中,并将其返回给语法糖
1赞
Andrey Agibalov
7/29/2011
@Lea Hayes:为什么?简单而惯用的解决方案。
0赞
Lea Hayes
7/29/2011
@loki2302,由于展开堆栈并调用析构函数,将会产生更多的开销(取决于优化器的好坏)。显式调用一个简单的函数,因此理论上它应该更有效。你可以避免定义结构/类,因为一个简单的函数就可以解决问题。只是我个人的喜好。
1赞
KillianDS
7/29/2011
@Lea:肉体过早优化......。对于现代编译器来说,这很可能不会有什么区别(RAII很重要,不要优化它)
0赞
Andrey Agibalov
7/29/2011
@Lea Hayes:嗯,理论上编译器可以做任何它想做的事,而语义是一样的。
0赞
Lea Hayes
7/29/2011
#2
int g() {
// blah
return 0;
}
void f() {
// do something
if (blabla)
return g();
// do something else
return g();
}
评论
0赞
Lea Hayes
7/29/2011
@Luchian对不起,我误读了你的问题,我已经更新了我的答案
2赞
laurent
7/29/2011
#3
对于这种事情,你可以简单地使用布尔值。这样你就没有太多的if/else语句了:
void f()
{
//do something
done = false;
if ( blabla )
done = true;
//do something else
if (!done) {
// some code
done = true;
}
if (!done) {
// some other code
done = true;
}
return;
}
2赞
2 revsravenspoint
#4
void f()
{
//do something
if ( blabla )
return;
//do something else
return;
//bla bla
}
void f_callg()
{
f();
g();
}
如果无法访问从中调用 f() 的位置
void f_copy_of_old()
{
//do something
if ( blabla )
return;
//do something else
return;
//bla bla
}
void f()
{
f_copy_of_old();
g();
}
7赞
mkaes
7/29/2011
#5
有一些方法可以做到这一点。
一种是使用 boost::scope_exit 或使用结构并在析构函数中完成工作。
我不喜欢 boost 的预处理器语法,而且我懒得编写结构,所以我更喜欢使用 boost::shared_ptr 或在较新的编译器上使用 std::shared_ptr。喜欢这个:
std::shared_ptr<void>(nullptr, [](void*){ /* do your stuff here*/ });
评论
0赞
Evan Teran
7/29/2011
+1,不错!事实上,我认为 Boost 应该有一个在 C++0x 编译器上利用这一点的 scope_exit 版本!
4赞
Mark B
7/29/2011
#6
这通常表明,与其在每次返回之前尝试人为地执行某些操作,不如尝试将函数重构为单退出形式。然后做你的额外步骤是超级容易的,因为......只有一次回报。
评论
0赞
mmmmmm
8/3/2012
如果抛出异常,会发生什么情况?
4赞
Ragesh Chakkadath
7/29/2011
#7
我认为 try-finally 语句会做你想做的事。
void f()
{
__try
{
//do something
if ( blabla )
return;
//do something else
return;
//bla bla
}
__finally
{
g();
}
}
try-finally 语句是 Microsoft 对 C 和 C++ 的扩展 使目标应用程序能够保证执行的语言 当代码块的执行中断时清理代码。清理 由取消分配内存、关闭文件和 释放文件句柄。try-finally 语句特别有用 对于具有多个位置的例程,可以对 可能导致例程过早返回的错误。
引自msdn。
评论
0赞
Andrey Agibalov
8/11/2011
它不是 C++,而是特定于 Microsoft 的扩展。
0赞
Ragesh Chakkadath
8/12/2011
在我的回答中已经提到过。它是 Microsoft 对 C 和 C++ 的扩展。但我不认为使用扩展会使它成为非 C++。
3赞
husky76
7/29/2011
#8
#define RETURN_IT g(); \
return;
void f()
{
//do something
if ( blabla )
RETURN_IT;
//do something else
RETURN_IT;
//bla bla
}
很简单,虽然我有点喜欢洛基的建议
上一个:代码重构后,正向声明会导致错误
下一个:运算符 [] 重载
评论
void call_f() { f(); g(); }