<commit_before>.. _api-trackable:
.. cpp:namespace:: qi::Trackable
.. cpp:auto_template:: True
.. default-role:: cpp:guess

qi::Trackable
*************

Rationale
=========

.. code-block:: cpp

  class MyClass {
    void callback();
  };

  qi::Signal<void> signal;

  MyClass* my = new MyClass();
  signal.connect(boost::bind(&MyClass::callback, my));
  delete my;

  signal(); // CRASH

In this code, the program will probably crash because the callback will be
called even though `my` has been destroyed.

Usage
=====

In this case, you need to use `qi::Trackable` with `qi::bind` so that the
callback won't be called when your object dies.

MyClass should inherit from `qi::Trackable<MyClass>` and the constructor must
call `qi::Trackable`'s constructor with ``this``. Then, you *must* call
`destroy()` at the *beginning* of your destructor. `destroy()` ensures that all
callbacks are finished before you start destructing your object. Then you must
use qi::bind instead of boost::bind which will do nothing if its first argument
is not valid anymore.

.. code-block:: cpp

  #include <qi/trackable.hpp>

  class MyClass : qi::Trackable<MyClass> {
    MyClass() : qi::Trackable<MyClass>(this)
    {}
    ~MyClass() {
      destroy();
    }

    void callback();
  };

  qi::Signal<void> signal;

  MyClass* my = new MyClass();
  signal.connect(qi::bind(&MyClass::callback, my));
  delete my;

  signal(); // callback won't be called, no crash

.. cpp:autoclass:: qi::Trackable

.. cpp:autofunction:: qi::bind<commit_msg>doc: fix qi::Trackable (no need for qi::bind)<commit_after>.. _api-trackable:
.. cpp:namespace:: qi::Trackable
.. cpp:auto_template:: True
.. default-role:: cpp:guess

qi::Trackable
*************

Rationale
=========

.. code-block:: cpp

  class MyClass {
    void callback();
  };

  qi::Signal<void> signal;

  MyClass* my = new MyClass();
  signal.connect(&MyClass::callback, my);
  delete my;

  signal(); // CRASH

In this code, the program will probably crash because the callback will be
called even though `my` has been destroyed.

Usage
=====

In this case, you need to use `qi::Trackable` with `qi::bind` so that the
callback won't be called when your object dies. Note that you usually don't
need to call `qi::bind` explicitely, `qi::Future::connect` and
`qi::Signal::connect` do it for you.

MyClass should inherit from `qi::Trackable<MyClass>` and the constructor must
call `qi::Trackable`'s constructor with ``this``. Then, you *must* call
`destroy()` at the *beginning* of your destructor. `destroy()` ensures that all
callbacks are finished before you start destructing your object. You must *not*
use ``boost::bind`` if you want your object to be tracked!

.. code-block:: cpp

  #include <qi/trackable.hpp>

  class MyClass : qi::Trackable<MyClass> {
    MyClass() : qi::Trackable<MyClass>(this)
    {}
    ~MyClass() {
      destroy();
    }

    void callback();
  };

  qi::Signal<void> signal;

  MyClass* my = new MyClass();
  signal.connect(&MyClass::callback, my);
  delete my;

  signal(); // callback won't be called, no crash

.. cpp:autoclass:: qi::Trackable

.. cpp:autofunction:: qi::bind
{'fraction_non_alphanumeric': 0.1519872813990461, 'fraction_numerical': 0.0, 'mean_word_length': 4.132137030995106, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7226609', 'n_tokens_mistral': 1043, 'n_tokens_neox': 987, 'n_words': 339}