IMP logo
IMP Reference Guide  develop.5651aa123e,2024/07/24
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-2022 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  Pointer<O>& operator=(std::nullptr_t o) {
105  P::operator=(o);
106  return *this;
107  }
108  Pointer<O>& operator=(const P& o) {
109  P::operator=(o);
110  return *this;
111  }
112 
113 #ifdef IMP_DOXYGEN
114  //! Relinquish control of the raw pointer stored in the Pointer
115  /** Use this to safely return objects allocated within functions.
116  The reference count of the object will be decreased by one,
117  but even it it becomes 0, the object will not be destroyed.
118 
119  @return a valid raw pointer to the object stored in Pointer
120  */
121  O* release();
122 
123  //! get the raw pointer to the object
124  O* get() const;
125 #endif
126 };
127 
128 //! A smart pointer to a ref-counted Object that is a class member
129 /** This class is identical
130  to Pointer, but in addition, Object::set_was_used(true) will be called so
131  you don't get warnings about unused objects once the object is stored in the
132  owning class.
133 
134  @note The object being pointed to must inherit from IMP::Object.
135 
136  \param[in] O The type of IMP::RefCounted-derived object to point to
137 
138  \see Pointer
139  \see WeakPointer
140  \see UncheckedWeakPointer
141  */
142 template <class O>
144  : IMP::internal::PointerBase<IMP::internal::PointerMemberTraits<O> > {
145  typedef IMP::internal::PointerBase<IMP::internal::PointerMemberTraits<O> > P;
146  template <class Any>
147  PointerMember(const Any& o)
148  : P(o) {}
149  PointerMember() {}
150  template <class OT>
151  PointerMember<O>& operator=(const IMP::internal::PointerBase<OT>& o) {
152  P::operator=(o);
153  return *this;
154  }
155  template <class OT>
156  PointerMember<O>& operator=(OT* o) {
157  P::operator=(o);
158  return *this;
159  }
160  PointerMember<O>& operator=(std::nullptr_t o) {
161  P::operator=(o);
162  return *this;
163  }
164  PointerMember<O>& operator=(const P& o) {
165  P::operator=(o);
166  return *this;
167  }
168 
169 #ifdef IMP_DOXYGEN
170  //! Relinquish control of the raw pointer stored in the PointerMember
171  /** Use this to safely return objects allocated within functions.
172  The reference count of the object will be decreased by one,
173  but even it it becomes 0, the object will not be destroyed.
174 
175  @return a valid raw pointer to the object stored in the PointerMember
176  */
177  O* release();
178 
179  //! get the raw pointer to the object
180  O* get() const;
181 #endif
182 };
183 
184 /******* streaming ********/
185 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
186 template <class T>
187 inline std::ostream& operator<<(std::ostream& out, Pointer<T> o) {
188  out << Showable(o.get());
189  return out;
190 }
191 template <class T>
192 inline std::ostream& operator<<(std::ostream& out, PointerMember<T> o) {
193  out << Showable(o.get());
194  return out;
195 }
196 #endif
197 
198 IMPKERNEL_END_NAMESPACE
199 
200 #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:143
A weak pointer to an Object or RefCountedObject.
Helper class to aid in output of IMP classes to streams.
Definition: Showable.h:25