IMP  2.4.0
The Integrative Modeling Platform
Pointer.h
Go to the documentation of this file.
1 /**
2  * \file IMP/base/Pointer.h
3  * \brief A nullptr-initialized pointer to an \imp Object.
4  *
5  * Copyright 2007-2015 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPBASE_POINTER_H
10 #define IMPBASE_POINTER_H
11 
12 #include <IMP/base/base_config.h>
13 #include "internal/PointerBase.h"
14 #include "WeakPointer.h"
15 
16 IMPBASE_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 kernel::Restraint that uses a
29  kernel::PairScore, store the kernel::PairScore like this:
30  \code
31  base::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 kernel::ParticlesTemp &ps)
38  {
39  IMP_NEW(core::LeavesRefiner, lr, (atom::Hierarchy::get_traits()));
40  base::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 kernel::ParticlesTemp
49  &ps)
50  {
51  base::Pointer<core::LeavesRefiner> lr
52  = new core::LeavesRefiner(atom::Hierarchy::get_traits());
53  base::Pointer<IMP::em::DensityMap> map
54  = em::read_map("file_name.mrc");
55  base::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::base::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::base::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 : internal::PointerBase<internal::RefCountedPointerTraits<O> > {
88  typedef internal::PointerBase<internal::RefCountedPointerTraits<O> > P;
89  template <class Any>
90  Pointer(const Any& o)
91  : P(o) {}
92  Pointer() {}
93  template <class OT>
94  base::Pointer<O>& operator=(const internal::PointerBase<OT>& o) {
95  P::operator=(o);
96  return *this;
97  }
98  template <class OT>
99  base::Pointer<O>& operator=(OT* o) {
100  P::operator=(o);
101  return *this;
102  }
103 #if (defined(BOOST_NO_CXX11_NULLPTR) || defined(BOOST_NO_NULLPTR)) && \
104  !defined(nullptr)
105  base::Pointer<O>& operator=(nullptr_t o) {
106  P::operator=(o);
107  return *this;
108  }
109 #endif
110  base::Pointer<O>& operator=(const P& o) {
111  P::operator=(o);
112  return *this;
113  }
114 
115 #ifdef IMP_DOXYGEN
116  //! Relinquish control of the raw pointer stored in the Pointer
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 /** A smart pointer to a reference counted Object, which is
133  meant to be stored as a class member. This class is identical
134  to Pointer, but in addition, Object::set_was_used(true) will be called so
135  you don't get warnings about unused objects once the object is stored in the
136  owning class.
137 
138  @note The object being pointed to must inherit from IMP::base::Object.
139 
140  \param[in] O The type of IMP::RefCounted-derived object to point to
141 
142  \see Pointer
143  \see WeakPointer
144  \see UncheckedWeakPointer
145  */
146 template <class O>
148  : internal::PointerBase<internal::PointerMemberTraits<O> > {
149  typedef internal::PointerBase<internal::PointerMemberTraits<O> > P;
150  template <class Any>
151  PointerMember(const Any& o)
152  : P(o) {}
153  PointerMember() {}
154  template <class OT>
155  base::PointerMember<O>& operator=(const internal::PointerBase<OT>& o) {
156  P::operator=(o);
157  return *this;
158  }
159  template <class OT>
160  base::PointerMember<O>& operator=(OT* o) {
161  P::operator=(o);
162  return *this;
163  }
164 #if (defined(BOOST_NO_CXX11_NULLPTR) || defined(BOOST_NO_NULLPTR)) && \
165  !defined(nullptr)
166  base::PointerMember<O>& operator=(nullptr_t o) {
167  P::operator=(o);
168  return *this;
169  }
170 #endif
171  base::PointerMember<O>& operator=(const P& o) {
172  P::operator=(o);
173  return *this;
174  }
175 
176 #ifdef IMP_DOXYGEN
177  //! Relinquish control of the raw pointer stored in the PointerMember
178  /** Relinquish control of the raw pointer stored in the PointerMember.
179  Use this to safely return objects allocated within functions.
180  The reference count of the object will be decreased by one,
181  but even it it becomes 0, the object will not be destroyed.
182 
183  @return a valid raw pointer to the object stored in the PointerMember
184  */
185  O* release();
186 
187  //! get the raw pointer to the object
188  O* get() const;
189 #endif
190 };
191 
192 /******* streaming ********/
193 #if !defined(IMP_DOXYGEN) && !defined(SWIG)
194 template <class T>
195 inline std::ostream& operator<<(std::ostream& out, base::Pointer<T> o) {
196  out << Showable(o.get());
197  return out;
198 }
199 template <class T>
200 inline std::ostream& operator<<(std::ostream& out, base::PointerMember<T> o) {
201  out << Showable(o.get());
202  return out;
203 }
204 #endif
205 
206 IMPBASE_END_NAMESPACE
207 
208 #endif /* IMPBASE_POINTER_H */
A smart pointer to a ref-counted Object that is a class member.
Definition: Pointer.h:147
A smart pointer to a reference counted object.
Definition: Pointer.h:87
A nullptr-initialized pointer to an Object.