IMP logo
IMP Reference Guide  develop.d247202c1c,2019/10/23
The Integrative Modeling Platform
Pointer.h
Go to the documentation of this file.
1 /**
2  * \file IMP/Pointer.h
3  * \brief A nullptr-initialized pointer to an \imp Object.
4  *
5  * Copyright 2007-2019 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_POINTER_H
10 #define IMPKERNEL_POINTER_H
11 
12 #include <IMP/kernel_config.h>
13 #include "internal/PointerBase.h"
14 #include "WeakPointer.h"
15 
16 IMPKERNEL_BEGIN_NAMESPACE
17 
18 //! A smart pointer to a reference counted object
19 /** Any time you store an Object in a C++ program, you should use a
20  Pointer, rather than a raw C++ pointer (or PointerMember, if the pointer
21  is stored in a class). Using a pointer manages
22  the reference counting and makes sure that the object is not deleted
23  prematurely when, for example, all Python references go away and
24  that it is deleted properly if an exception is thrown during the
25  function.
26  Use the IMP_NEW() macro to aid creation of pointers to new objects.
27 
28  For example, when implementing a Restraint that uses a
29  PairScore, store the PairScore like this:
30  \code
31  PointerMember<PairScore> ps_;
32  \endcode
33 
34  When creating Object instances in C++, you should write code like:
35  \code
36  em::FitRestraint* create_fit_restraint(std::string mapname,
37  const ParticlesTemp &ps)
38  {
39  IMP_NEW(core::LeavesRefiner, lr, (atom::Hierarchy::get_traits()));
40  Pointer<em::DensityMap> map= em::read_map("file_name.mrc");
41  IMP_NEW(em::FitRestraint, fr, (ps, map, lr));
42  return fr.release();
43  }
44  \endcode
45  which is equivalent to
46  \code
47  IMP::em::FitRestraint* create_fit_restraint(std::string mapname,
48  const ParticlesTemp
49  &ps)
50  {
51  Pointer<core::LeavesRefiner> lr
52  = new core::LeavesRefiner(atom::Hierarchy::get_traits());
53  Pointer<IMP::em::DensityMap> map
54  = em::read_map("file_name.mrc");
55  Pointer<em::FitRestraint> fr
56  = new em::FitRestraint(ps, map, lr));
57  return fr.release();
58  }
59  \endcode
60  There are several important things to note in this code:
61  - the use of Pointer::release() on the return. Otherwise, when the
62  reference counted pointer goes out of scope, it will unref the
63  em::FitRestraint, notice the count is 0, and delete it, before
64  passing the (now invalid) pointer back to the calling function
65  - the use of reference counted pointers everywhere. This ensures
66  that if, for example, em::read_map() throws an exception since the
67  file name is invalid, the core::LeavesRefiner will be deleted
68  properly.
69 
70  \note Do not pass Pointers as arguments to functions; pass raw C++
71  pointers instead.
72 
73  \note Consider using IMP::PointerMember when storing pointers to
74  ref-counted objects as class members (the only difference is that
75  the object will be marked by the pointer as 'used')
76 
77  \note Use IMP::WeakPointer to break cycles or to point to
78  non-ref-counted objects.
79 
80  \param[in] O The type of RefCounted-derived object to point to
81 
82  \see PointerMember
83  \see WeakPointer
84  \see UncheckedWeakPointer
85  */
86 template <class O>
87 struct Pointer
88  : IMP::internal::PointerBase<IMP::internal::RefCountedPointerTraits<O> > {
89  typedef IMP::internal::PointerBase<IMP::internal::RefCountedPointerTraits<O> > P;
90  template <class Any>
91  Pointer(const Any& o)
92  : P(o) {}
93  Pointer() {}
94  template <class OT>
95  Pointer<O>& operator=(const IMP::internal::PointerBase<OT>& o) {
96  P::operator=(o);
97  return *this;
98  }
99  template <class OT>
100  Pointer<O>& operator=(OT* o) {
101  P::operator=(o);
102  return *this;
103  }
104 #if (defined(BOOST_NO_CXX11_NULLPTR) || defined(BOOST_NO_NULLPTR)) && \
105  !defined(nullptr)
106  Pointer<O>& operator=(nullptr_t o) {
107  P::operator=(o);
108  return *this;
109  }
110 #endif
111  Pointer<O>& operator=(const P& o) {
112  P::operator=(o);
113  return *this;
114  }
115 
116 #ifdef IMP_DOXYGEN
117  //! Relinquish control of the raw pointer stored in the Pointer
118  /** Use this to safely return objects allocated within functions.
119  The reference count of the object will be decreased by one,
120  but even it it becomes 0, the object will not be destroyed.
121 
122  @return a valid raw pointer to the object stored in Pointer
123  */
124  O* release();
125 
126  //! get the raw pointer to the object
127  O* get() const;
128 #endif
129 };
130 
131 //! A smart pointer to a ref-counted Object that is a class member
132 /** This class is identical
133  to Pointer, but in addition, Object::set_was_used(true) will be called so
134  you don't get warnings about unused objects once the object is stored in the
135  owning class.
136 
137  @note The object being pointed to must inherit from IMP::Object.
138 
139  \param[in] O The type of IMP::RefCounted-derived object to point to
140 
141  \see Pointer
142  \see WeakPointer
143  \see UncheckedWeakPointer
144  */
145 template <class O>
147  : IMP::internal::PointerBase<IMP::internal::PointerMemberTraits<O> > {
148  typedef IMP::internal::PointerBase<IMP::internal::PointerMemberTraits<O> > P;
149  template <class Any>
150  PointerMember(const Any& o)
151  : P(o) {}
152  PointerMember() {}
153  template <class OT>
154  PointerMember<O>& operator=(const IMP::internal::PointerBase<OT>& o) {
155  P::operator=(o);
156  return *this;
157  }
158  template <class OT>
159  PointerMember<O>& operator=(OT* o) {
160  P::operator=(o);
161  return *this;
162  }
163 #if (defined(BOOST_NO_CXX11_NULLPTR) || defined(BOOST_NO_NULLPTR)) && \
164  !defined(nullptr)
165  PointerMember<O>& operator=(nullptr_t o) {
166  P::operator=(o);
167  return *this;
168  }
169 #endif
170  PointerMember<O>& operator=(const P& o) {
171  P::operator=(o);
172  return *this;
173  }
174 
175 #ifdef IMP_DOXYGEN
176  //! Relinquish control of the raw pointer stored in the PointerMember
177  /** Use this to safely return objects allocated within functions.
178  The reference count of the object will be decreased by one,
179  but even it it becomes 0, the object will not be destroyed.
180 
181  @return a valid raw pointer to the object stored in the PointerMember
182  */
183  O* release();
184 
185  //! get the raw pointer to the object
186  O* get() const;
187 #endif
188 };
189 
190 /******* streaming ********/
191 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
192 template <class T>
193 inline std::ostream& operator<<(std::ostream& out, Pointer<T> o) {
194  out << Showable(o.get());
195  return out;
196 }
197 template <class T>
198 inline std::ostream& operator<<(std::ostream& out, PointerMember<T> o) {
199  out << Showable(o.get());
200  return out;
201 }
202 #endif
203 
204 IMPKERNEL_END_NAMESPACE
205 
206 #endif /* IMPKERNEL_POINTER_H */
A smart pointer to a reference counted object.
Definition: Pointer.h:87
A smart pointer to a ref-counted Object that is a class member.
Definition: Pointer.h:146
A nullptr-initialized pointer to an Object.