Like the title.
As a new programmer,It is very important to know the mechanism for my project, and what is the difference of using them. Can any guy give me a answer,thank you!
Like the title. As a new programmer,It is very important to know the mechanism
Share
A virtual function is one mechanism to provide a callback, but it is not the only mechanism.
The generality of a callback is that you pass in, as a parameter, a method, or an object that invokes a method, that will be called by the function you pass it to, or will be stored by that function to be called later when an event happens.
One way to implement such a mechanism is to pass in a pointer or reference to an object that derives from a base class and implements a virtual function.
Another way is to pass in a function pointer.
Yet another is to pass in an object that has a function pointer, which is what boost functions are – the constructors to boost function (often
boost::bind) cleverly construct such an object for you.In C++11 you will be able to construct an unnamed function on the fly to be passed as a callback. This is usually referred to as a lambda.
A bit more about the mechanism of using a virtual function as a callback. It can look like quite a neat thing to do:
Even tidier is to construct Handler this way:
The advantage here is that it is easy to debug into.
It becomes more complex if the lifetime of the Handler object needs to be managed, i.e. the callback happens asynchronously. Then you have to use a
shared_ptr<Handler>so that both sides hold a reference, and it will be managed.One huge advantage you will find by doing this, over a regular callback function, is that the object can hold extra information. The callback itself can only take a fixed number of parameters, and in a callback one will often use a void* and have to cast it to something to get back the extra information. Using the class allows you to hold that information in member variables, as well as allowing the class to retain state after its method was invoked.
The overhead of using this though is that you have to create such abstract classes and then derive classes from it, and you might find yourself doing this rather a lot.
This is where boost function and bind becomes very useful. What you really want is a function with a specific signature to be called, and not to have to create extra classes to handle this callback. It enables you therefore to program this situation much more quickly.
However, it unfortunately does have a downside too. boost functions are far more difficult to be able to debug into. Whilst you do not have to be careful about managing the lifetime of the boost function itself, you do have to be careful about the parameters you pass into it. It will just blindly store them the way you pass them. If you pass in a reference to local variable as a reference-holder (
boost::ref) it will indeed store this reference and if it happens to go out of scope before the function is invoked, you may have a hard time locating this bug.In spite of this though, I would suggest making use of the library feature (note there is also std::function and std::bind, although when lambdas become standard among compilers, there will be far less requirement for them).