【发布时间】:2010-10-20 01:31:26
【问题描述】:
而不是每次都执行以下操作
start();
// some code here
stop();
我想定义某种宏,它可以写成这样:
startstop()
{
//code here
}
在 C++ 中可以吗?
【问题讨论】:
而不是每次都执行以下操作
start();
// some code here
stop();
我想定义某种宏,它可以写成这样:
startstop()
{
//code here
}
在 C++ 中可以吗?
【问题讨论】:
在 C++ 中执行此操作的惯用方式称为 Resource Acquisition Is Initialization,或简称为 RAII。除了提供你想要的东西之外,它还有一个额外的好处是异常安全:即使你的代码抛出异常,stop 函数也会被调用。
定义一个保护结构:
struct startstop_guard
{
startstop_guard()
{
start();
}
~startstop_guard()
{
stop();
}
};
然后用这种方式重写你的代码:
{
startstop_guard g;
// your code
}
守卫的析构函数(以及 stop 函数)将在封闭块的末尾自动调用。
【讨论】:
你想做什么?我建议将RAII 视为一种比宏黑客更面向 C++ 的做事方式,它会带来所有无法预料的后果。
【讨论】:
您可以使用一个小的 C++ 帮助类来做一些非常接近的事情。
class StartStopper {
public:
StartStopper() { start(); }
~StartStopper() { stop(); }
};
然后在你的代码中:
{
StartStopper ss;
// code here
}
当执行进入块并构造ss变量时,start()函数将被调用。当执行离开块时,会自动调用StartStopper析构函数,然后调用stop()。
【讨论】:
#define startstop(x, y, ...) for( /* use macro args */ )
【讨论】:
不要使用宏。您可以改用内联函数,因为它提供类型检查和其他功能。你可以看这里:inline functions
【讨论】:
具有 RAII 和 boost::function ( std::function ) 的通用解决方案。
class starter
{
typedef boost::function< void () > action;
action end_;
public:
starter(action start, action end):
end_(end)
{
log("starter start");
start();
}
~starter()
{
log("starter end");
end_() ;
}
};
int main()
{
{
starter s(start, stop);
middle();
}
return 0;
}
或测试和检查这个想法
void print(const std::string& message)
{
std::cout << message << std::endl;
}
int main()
{
starter s(boost::bind(print, "globalstart"),
boost::bind(print, "globalend"));
{
starter s(boost::bind(print, "start"),
boost::bind(print, "end"));
std::cout << "middle" << std::endl;
}
return 0;
}
【讨论】:
其他答案已经很好地解决了问题的 RAII 方面,所以我将解决它的语法方面。
#define startstop for(Starter s; s.loop; s.loop = false)
struct Starter {
bool loop;
Starter() { start(); loop = true; }
~Starter() { stop(); }
};
类似:
startstop {
// some code
}
应该足够不言自明。
【讨论】:
在 c# 中,您可以使用 IDisposable 模式,并在 Dispose() 方法中实现您的 Stop() 功能,但如果您使用的是 c++ 的 .net 变体,这将起作用。
【讨论】:
归功于这个想法。我想我会填写其余的
#define startstop() for(start();isStarted();stop())
【讨论】: