而不是每次都做以下
start();
// some code here
stop();
我想定义一些宏,它可以写成:
startstop()
{
//code here
}
是否可以在C ++中使用?
答案 0 :(得分:40)
使用小型C ++帮助程序类可以非常接近。
class StartStopper {
public:
StartStopper() { start(); }
~StartStopper() { stop(); }
};
然后在你的代码中:
{
StartStopper ss;
// code here
}
当执行进入块并构造ss
变量时,将调用start()
函数。当执行离开块时,将自动调用StartStopper
析构函数,然后调用stop()
。
答案 1 :(得分:14)
在C ++中执行此操作的惯用方法称为Resource Acquisition Is Initialization,或称为RAII。除了提供您想要的内容之外,它还具有异常安全的额外好处:即使您的代码抛出异常,也会调用stop
函数。
定义一个保护结构:
struct startstop_guard
{
startstop_guard()
{
start();
}
~startstop_guard()
{
stop();
}
};
然后以这种方式重写代码:
{
startstop_guard g;
// your code
}
将在封闭块的末尾自动调用guard的析构函数(以及stop
函数)。
答案 2 :(得分:6)
其他答案已经很好地解决了问题的RAII方面,所以我将解决它的语法方面。
#define startstop for(Starter s; s.loop; s.loop = false)
struct Starter {
bool loop;
Starter() { start(); loop = true; }
~Starter() { stop(); }
};
像一样使用:
startstop {
// some code
}
应该不言自明。
答案 3 :(得分:4)
#define startstop(x, y, ...) for( /* use macro args */ )
答案 4 :(得分:2)
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;
}
答案 5 :(得分:1)
你想做什么?我建议将RAII作为一种更多面向C ++的做事方式,而不是宏观黑客攻击,以及所有不可预见的后果。
答案 6 :(得分:1)
不要使用宏。您可以使用内联函数,因为它提供了类型检查和其他功能。你可以看看这里:inline functions
答案 7 :(得分:1)
答案 8 :(得分:0)
在c#中,您可以使用IDisposable模式,并在Dispose()方法中实现Stop()功能,但如果您使用的是c ++的.net变体,那将会有效。