SurgSim::Framework::SharedInstance< T > Class Template Reference

A utility class to manage a shared instance of an object. More...

`#include <SurgSim/Framework/SharedInstance.h>`

## Public Types

typedef std::function< std::shared_ptr< T >)> | InstanceCreator
| A type that can hold a function object or lambda that takes no arguments and returns std::shared_ptr<T>. More...

## Public Member Functions

| SharedInstance ()
| Create the SharedInstance object used to manage the shared instance. More...
| SharedInstance (const InstanceCreator &instanceCreator)
| Create the SharedInstance object used to manage the shared instance. More...
| ~SharedInstance ()
| Destroy the container and the data it contains. More...
std::shared_ptr< T > | get ()
| Gets the shared object instance. More...

## Private Member Functions

| SharedInstance (const SharedInstance &)
| Prevent copying. More...
SharedInstance & | operator= (const SharedInstance &)
| Prevent assignment. More...
std::shared_ptr< T > | createInstance ()
| Creates an object instance. More...

## Static Private Member Functions

static InstanceCreator | defaultInstanceCreator ()
| Creates a function that can create an instance using std::make_shared<T>(). More...

## Private Attributes

InstanceCreator | m_instanceCreator
| A creator function used to construct the shared instance. More...
std::weak_ptr< T > | m_weakInstance
| A weak reference to the shared instance, if any. More...
boost::mutex | m_mutex
| Mutex for synchronization of object creation. More...

## Detailed Description

### template<typename T>
class SurgSim::Framework::SharedInstance< T >

A utility class to manage a shared instance of an object.

This class behaves in a way that is superficially similar to the Singleton pattern, in that it manages a single shared instance of an object. However, there are some important differences to note:

- The Singleton pattern applies to a particular class, so that a single instance is shared between any and all uses of that class. The SharedInstance case applies to a specific use of a class: the user creates a (shared) SharedInstance<T> object that manages the sharing of one instance of T. It is possible for another SharedInstance<T> that manages the same type T to be created elsewhere. This second SharedInstance manages a second, separate instance of T.
- The object will not only be created as needed, but also destroyed when all of the shared_ptr references to it are released. If it is released and then needed again, a new instance will be created.
- This life-cycle management based on reference counting makes it imperative for the calling code to hold onto their own shared_ptr for as long as they want to interact with the shared object instance. Releasing the shared_ptr indicates that the code using it is ready for the instance to be potentially destroyed.

Code using this class will normally use the get() method to initialize its own shared_ptr referencing the shared instance. Such code should hold onto the shared_ptr for as long as it needs to use the shared instance. As soon as all of the shared pointers are released, the shared object instance will be destroyed.

A Simple Example

To share an instance between many objects in the same class, you can declare a static SharedInstance member:

class ManyObjects
{
ManyObjects() : m_sharedInstance(m_sharedInstanceManager.get())
{
}
// ...
std::shared_ptr<SingleObject> m_sharedInstance;
static SurgSim::Framework::SharedInstance<SingleObject> m_sharedInstanceManager;
}
// Need to also define the static member somewhere:
SurgSim::Framework::SharedInstance<SingleObject> ManyObjects::m_sharedInstanceManager;

The downside to this approach is that it requires the SharedInstance object itself to be created as a static member of a class. Since the order of construction (and destruction) of various static data members is not well defined by the C++ language standards, this can lead to objects getting used before they are initialized.

A Better Example

To avoid the initialization order problems, you can instead use the SharedInstance as a static variable inside a function or a (most likely also static) method, so it will not be initialized until that function/method is first called. (Note that this is only safe if your compiler follows the C++11 requirement that the initialization of static variables inside functions must be atomic.)

class ManyObjects
{
ManyObjects() : m_sharedInstance(getSharedInstance())
{
}
// ...
static std::shared_ptr<SingleObject> getSharedInstance();
std::shared_ptr<SingleObject> m_sharedInstance;
}
std::shared_ptr<SingleObject> ManyObjects::getSharedInstance()
{
static SharedInstance<SingleObject> shared;
return shared.get();
}

Template Parameters

  T | Type of the data held by the SharedInstance.

## Member Typedef Documentation

## InstanceCreator

template<typename T>

typedef std::function<std::shared_ptr<T>)> SurgSim::Framework::SharedInstance< T >::InstanceCreator

A type that can hold a function object or lambda that takes no arguments and returns std::shared_ptr<T>.

## Constructor & Destructor Documentation

## SharedInstance() [1/3]

template<typename T >

SurgSim::Framework::SharedInstance< T >::SharedInstance | ( |  | ) |

Create the SharedInstance object used to manage the shared instance.

Note that this does not immediately create the instance itself. If and when the shared instance is created, it will be initialized using the default constructor via std::make_shared.

## SharedInstance() [2/3]

template<typename T >

SurgSim::Framework::SharedInstance< T >::SharedInstance | ( | const InstanceCreator & | instanceCreator | ) |

explicit

Create the SharedInstance object used to manage the shared instance.

Note that this does not immediately create the instance itself. If and when the shared instance is created, it will be initialized using the creator call.

## ~SharedInstance()

template<typename T >

SurgSim::Framework::SharedInstance< T >::~SharedInstance | ( |  | ) |

Destroy the container and the data it contains.

## SharedInstance() [3/3]

template<typename T>

SurgSim::Framework::SharedInstance< T >::SharedInstance | ( | const SharedInstance< T > & |  | ) |

private

Prevent copying.

## Member Function Documentation

## createInstance()

template<typename T >

std::shared_ptr< T > SurgSim::Framework::SharedInstance< T >::createInstance | ( |  | ) |

private

Creates an object instance.

Returns
  a shared_ptr containing a newly created object instance.

## defaultInstanceCreator()

template<typename T >

SharedInstance< T >::InstanceCreator SurgSim::Framework::SharedInstance< T >::defaultInstanceCreator | ( |  | ) |

static private

Creates a function that can create an instance using std::make_shared<T>().

The function must be default-constuctible. It was necessary to split this into a separate function because with VS2010, we can't just put a lambda in the initializer for m_instanceCreator.

Returns
  a function that creates a new object of type T using std::make_shared.

## get()

template<typename T >

std::shared_ptr< T > SurgSim::Framework::SharedInstance< T >::get | ( |  | ) |

Gets the shared object instance.

If the instance has not been created previously, it will be created during the call.

The calling code should generally copy the shared_ptr and hold onto it for as long as needed. As soon as all of the shared pointers are released, the shared object instance will be destroyed.

Returns
  a shared_ptr holding the instance.

## operator=()

template<typename T>

SharedInstance& SurgSim::Framework::SharedInstance< T >::operator= | ( | const SharedInstance< T > & |  | ) |

private

Prevent assignment.

## Member Data Documentation

## m_instanceCreator

template<typename T>

InstanceCreator SurgSim::Framework::SharedInstance< T >::m_instanceCreator

private

A creator function used to construct the shared instance.

## m_mutex

template<typename T>

boost::mutex SurgSim::Framework::SharedInstance< T >::m_mutex

private

Mutex for synchronization of object creation.

## m_weakInstance

template<typename T>

std::weak_ptr<T> SurgSim::Framework::SharedInstance< T >::m_weakInstance

private

A weak reference to the shared instance, if any.

The documentation for this class was generated from the following files:

- SurgSim/Framework/SharedInstance.h
- SurgSim/Framework/SharedInstance-inl.h