Does using callbacks in C++ increase coupling?

前端 未结 8 1744
予麋鹿
予麋鹿 2021-01-03 11:04

Q1. Why are callback functions used?

Q2. Are callbacks evil? Fun for those who know, for others a nightmare.

Q3. Any alternative to

相关标签:
8条回答
  • 2021-01-03 11:26

    Callbacks decrease coupling - the invoked party is passed some pointer and it has no idea what's behind it. Callbacks are such a fortunate solution that they are very widespread.

    For example look at sqlite3_exec(). You give it a query and optionally a callback. It executes the query and invokes the callback for each row as it is retrieved. Now it's SQLite's business to execute the query fast and with low resource consumtion and it's only your business to process the retrieved results as you like. You can add them to a container and process all later or you can process them immediately one-by-one or you can fax them somewhere and expect the other party to fax them back - SQLite doesn't care, it's completely abstracted and can just do its job.

    0 讨论(0)
  • 2021-01-03 11:27

    In rare scenarios with Win32-style-callbacks watch out for "obscure reentrancy" issues (the following is irrelevant if by callback you just mean very basic passing of a function as arg to another function where concurrency issues are unimaginable ).
    The excellent index to Joe Duffy's "Concurrent Programming on Windows" lists 5 topics under "reentrancy", which generally are specializations of the concept of "Around Robin-Hood's Barn RECURSION on the SAME THREAD" -- in other words from the top-rated-answer "the invoked party is passed some pointer and it has no idea what's behind it.", "no idea" can sometimes lead around-Robin-Hood's-barn.
    Nothing I just said is specific to callbacks, but if the invoked-party stumbles across one of Duffy's scenarios then "obscure reentrancy" can happen. To put it a different way, implicit in the concept of "callback" is that you're going to seem to be called back in-the-same-thread, how does this happen, how does it get synchronized.
    If you Google on Duffy's book-title and tack the word Callback onto your search then you get more than 10 pages of hits.

    0 讨论(0)
  • 2021-01-03 11:29
    1. Callbacks are used for example to invoke aynchronous operations, that is, code that runs in a different thread while the caller follows its own way. You need some mechanism to know when the asyncrhonous operation has finished.

    2. Why would them be evil? As with any other programming resource, they are useful when used judiciously. In fact the Windows API and the .NET framework, for example, use callbacks extensively.

    3. Don't know about C++, but in the .NET world, syncronization objects and events are alternatives.

    0 讨论(0)
  • 2021-01-03 11:29

    If we in C++ context, consider using (e.g. generalized callbacks).

    The basic behaind idea is that callback (class method) can be of any name and the callback is not required to derive from some class knowned by callback executor.

    The only restriction on callback is input arguments and return value. So this reduces couple to zero ... :)

    UDP:

    Answer of @EffoStaff Effo is an example where callback should be of the particular class (deriving) and have a fix name. All this "restrictions" are absent in context of generalize callbacks.

    0 讨论(0)
  • 2021-01-03 11:32
    1. Callbacks decrease coupling as they allow you to write code that calls a function that can be changed
    2. Callbacks are not evil, just that if you are using raw function pointers things can get messy really fast.
    3. There isn't an alternative to callbacks per se, but there are alternatives to using raw function pointers.

    A post pointing to Boost was made earlier for Boost.Function. If you are looking for a more generic solution for callbacks, such as multiple functions attached to the same callback or something like that, consider using Boost.Signals. The name comes from signals and slots, which is the way some people refer to callbacks nowadays, especially for GUIs.

    0 讨论(0)
  • 2021-01-03 11:35

    Q1. Callbacks are needed if you use a layered approach in which higher levels call lowers and get feedback from lowers via callback.
    Q2. When taken some precautions they're not worse than e.g. exceptions. In some ways, they're similar. Q3. More coupling: lower lovels know higher.

    Remarks:
    - simple way (1 callback handler per callback): Register CallbackHandler objects via interfaces
    - Use signals (QT, boost,...), and make sure that unique signals are used per callback to enhance traceability

    Edit: example:

    User calls ProtocolHandler to send a message and ProtocolHandler calls the user to send the reply: mutual dependency.

    Layered: user is higher level, ProtocolHandler is lower level. On startup, it registers a callback for the reply and calls the ProtocolHandler to send a message. The ProtocolHandler uses the callback to send the reply: Only user is dependent of ProtocolHandler.

    0 讨论(0)
提交回复
热议问题