IMP  2.2.1
The Integrative Modeling Platform
IMP::base::Pointer< O > Struct Template Reference

A smart pointer to a reference counted object. More...

#include <IMP/base/Pointer.h>

+ Inheritance diagram for IMP::base::Pointer< O >:

Public Types

typedef internal::PointerBase
< internal::RefCountedPointerTraits
< O > > 
P
 

Public Member Functions

template<class Any >
 Pointer (const Any &o)
 
O * get () const
 get the raw pointer to the object
 
template<class OT >
base::Pointer< O > & operator= (const internal::PointerBase< OT > &o)
 
template<class OT >
base::Pointer< O > & operator= (OT *o)
 
base::Pointer< O > & operator= (const P &o)
 
O * release ()
 Relinquish control of the raw pointer stored in the Pointer. More...
 

Detailed Description

template<class O>
struct IMP::base::Pointer< O >

Any time you store an Object in a C++ program, you should use a Pointer, rather than a raw C++ pointer (or PointerMember, if the pointer is stored in a class). Using a pointer manages the reference counting and makes sure that the object is not deleted prematurely when, for example, all Python references go away and that it is deleted properly if an exception is thrown during the function. Use the IMP_NEW() macro to aid creation of pointers to new objects.

For example, when implementing a kernel::Restraint that uses a kernel::PairScore, store the kernel::PairScore like this:

base::PointerMember<PairScore> ps_;

When creating Object instances in C++, you should write code like:

em::FitRestraint* create_fit_restraint(std::string mapname,
const kernel::ParticlesTemp &ps)
{
IMP_NEW(core::LeavesRefiner, lr, (atom::Hierarchy::get_traits()));
base::Pointer<em::DensityMap> map= em::read_map("file_name.mrc");
IMP_NEW(em::FitRestraint, fr, (ps, map, lr));
return fr.release();
}

which is equivalent to

IMP::em::FitRestraint* create_fit_restraint(std::string mapname,
const kernel::ParticlesTemp
&ps)
{
base::Pointer<core::LeavesRefiner> lr
= new core::LeavesRefiner(atom::Hierarchy::get_traits());
base::Pointer<IMP::em::DensityMap> map
= em::read_map("file_name.mrc");
base::Pointer<em::FitRestraint> fr
= new em::FitRestraint(ps, map, lr));
return fr.release();
}

There are several important things to note in this code:

  • the use of Pointer::release() on the return. Otherwise, when the reference counted pointer goes out of scope, it will unref the em::FitRestraint, notice the count is 0, and delete it, before passing the (now invalid) pointer back to the calling function
  • the use of reference counted pointers everywhere. This ensures that if, for example, em::read_map() throws an exception since the file name is invalid, the core::LeavesRefiner will be deleted properly.
Note
Do not pass Pointers as arguments to functions; pass raw C++ pointers instead.
Consider using IMP::base::PointerMember when storing pointers to ref-counted objects as class members (the only difference is that the object will be marked by the pointer as 'used')
Use IMP::base::WeakPointer to break cycles or to point to non-ref-counted objects.
Parameters
[in]OThe type of RefCounted-derived object to point to
See Also
PointerMember
WeakPointer
UncheckedWeakPointer

Definition at line 87 of file base/Pointer.h.

Member Function Documentation

template<class O>
O* IMP::base::Pointer< O >::release ( )

Relinquish control of the raw pointer stored in the Pointer. Use this to safely return objects allocated within functions. The reference count of the object will be decreased by one, but even it it becomes 0, the object will not be destroyed.

Returns
a valid raw pointer to the object stored in Pointer

The documentation for this struct was generated from the following file: