Hi, Instead of doing the following everytime
start();
// some code here
stop();
I would like to define some sort of macro which makes it possible to write like:
startstop()
{
//code here
}
Is it possible in C++?
Hi, Instead of doing the following everytime
start();
// some code here
stop();
I would like to define some sort of macro which makes it possible to write like:
startstop()
{
//code here
}
Is it possible in C++?
The idiomatic way of doing this in C++ is called Resource Acquisition Is Initialization, or shortly RAII. In addition to providing what you want, it also has the added benefit of being exception safe: the stop
function will be called even if your code throws an exception.
Define a guard struct:
struct startstop_guard
{
startstop_guard()
{
start();
}
~startstop_guard()
{
stop();
}
};
and then rewrite your code this way:
{
startstop_guard g;
// your code
}
The guard's destructor (and thus the stop
function) will be called automatically at the end of the enclosing block.
What are you trying to do? I'd recommend checking out RAII as a much more C++ oriented way of doing things than macro hacking, with all its unforeseen consequences.
You can do something very close using a small C++ helper class.
class StartStopper {
public:
StartStopper() { start(); }
~StartStopper() { stop(); }
};
Then in your code:
{
StartStopper ss;
// code here
}
When execution enters the block and constructs the ss
variable, the start()
function will be called. When execution leaves the block, the StartStopper
destructor will be automatically called and will then call stop()
.
Don't use macros. You can use inline functions instead as it provides type checking and other features. You can take a look here: inline functions
Generic solution with RAII and 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;
}
or to test and check the idea
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;
}
Other answers have addressed the RAII side of the question well, so I'm going to address the syntax side of it.
#define startstop for(Starter s; s.loop; s.loop = false)
struct Starter {
bool loop;
Starter() { start(); loop = true; }
~Starter() { stop(); }
};
Used like:
startstop {
// some code
}
Should be self-explanatory enough.
In c#, you could use the IDisposable pattern, and implement your Stop() functionality in the Dispose() method, but that would would work if you were using a .net variant of c++.