Aldebaran documentation What's new in NAOqi 2.4.3?

qi::Trackable

Summary

Global Namespaces

Detailed Description

Rationale

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 explicitly, qi::Future::connect and qi::Signal::connect do it for you.

MyClass should inherit from qi::Trackable 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!

#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

Reference

qi::Trackable Class Reference

Introduction

Object tracking by blocking destruction while shared pointers are present. More...

#include <qi/trackable.hpp>
  • Inherits: qi::TrackableBase

Public Functions

Trackable(T* ptr)
~Trackable()
boost::shared_ptr<T> lock()
boost::weak_ptr<T> weakPtr()
void wait()

Detailed Description

Inherit from Trackable to allow a form of tracking that blocks destruction while shared pointers are held. This allows using your class without a shared_ptr wrapper.

when inheriting from this class, you must invoke the destroy() method from your destructor, before any operation that puts your object in an invalid state.since destroy() blocks until all shared pointers are destroyed, deadlocks may occur if used improperly.

Function Documentation

qi::Trackable<T>::Trackable(T* ptr)

Default constructor.

qi::Trackable<T>::~Trackable()

Default destructor.

boost::shared_ptr<T> qi::Trackable<T>::lock()

Brief:

Returns:A shared_ptr that will block destruction (call to destroy() until it is released, or an empty shared_ptr if destroy was already called.
boost::weak_ptr<T> qi::Trackable<T>::weakPtr()

Brief:

Returns:A weak_ptr from this. While a shared_ptr exists from this weak_ptr, a call to destroy will block()
void qi::Trackable<T>::wait()

Blocks until destroy() is called and all shared_ptr built from weak_ptr() are deleted.

template<typename RF, typename AF>
boost::function<RF> qi::bind(const AF& fun, ...)

Bind a set of arguments or placeholders to a function.

Handles first function argument of kind boost::weak_ptr and qi::Trackable: will try to lock and throw qi::PointerLockException in case of failure