IMP
2.0.0
The Integrative Modeling Platform
Main Page
Related Pages
Modules
Namespaces
Classes
Files
Examples
File List
File Members
base/RefCounted.h
Go to the documentation of this file.
1
/**
2
* \file IMP/base/RefCounted.h
3
* \brief A common base class for ref counted objects.
4
*
5
* Copyright 2007-2013 IMP Inventors. All rights reserved.
6
*
7
*/
8
9
#ifndef IMPBASE_REF_COUNTED_H
10
#define IMPBASE_REF_COUNTED_H
11
12
#include <IMP/base/base_config.h>
13
#include "
exception.h
"
14
#include "
utility_macros.h
"
15
#include <boost/static_assert.hpp>
16
#include <boost/type_traits.hpp>
17
#include "
NonCopyable.h
"
18
19
20
#ifndef IMP_DOXYGEN
21
#ifndef SWIG
22
23
namespace
IMP {
24
namespace
base {
25
class
Object;
26
namespace
internal {
27
template
<
class
R,
class
E>
28
struct
RefStuff;
29
}
30
}
31
}
32
#endif
33
#endif
34
35
IMPBASE_BEGIN_NAMESPACE
36
37
38
//! Common base class for ref counted objects.
39
/** This base class implements reference counting when used in
40
conjunction with IMP::Pointer or IMP::WeakPointer objects.
41
Objects which inherit from IMP::RefCounted should be passed
42
using pointers and stored using IMP::Pointer and
43
IMP::WeakPointer objects. Users must be careful to avoid
44
cycles of reference counted pointers, otherwise memory will
45
never be reclaimed.
46
47
\par Introduction to reference counting:
48
Reference counting is a technique for managing memory and
49
automatically freeing memory (destroying objects) when it
50
is no longer needed. In reference counting, each object has a reference
51
count, which tracks how many different places are using the
52
object. When this count goes to 0, the object is freed.\n\n
53
Python internally refence counts everything. C++, on the other hand,
54
requires extra steps be taken to ensure that objects
55
are reference counted properly.\n\n
56
In \imp, reference counting is done through the IMP::Pointer
57
and IMP::RefCounted classes. The former should be used instead of
58
a raw C++ pointer when storing a pointer to any object
59
inheriting from IMP::RefCounted.\n\n
60
Any time one is using reference counting, one needs to be aware
61
of cycles, since if, for example, object A contains an IMP::Pointer to
62
object B and object B contains an IMP::Pointer to object A,
63
their reference counts will never go to 0 even if both A
64
and B are no longer used. To avoid this, use an
65
IMP::WeakPointer in one of A or B.
66
67
IMP::RefCounted provides no public methods or constructors.
68
It makes objects that inherit from it non-copyable.
69
70
\see IMP_REF_COUNTED_DESTRUCTOR()
71
*/
72
class
IMPBASEEXPORT
RefCounted
:
public
NonCopyable
73
{
74
#ifndef IMP_DOXYGEN
75
static
unsigned
int
live_objects_;
76
77
void
init() {
78
#if IMP_HAS_CHECKS >= IMP_INTERNAL
79
++live_objects_;
80
#endif
81
#if IMP_HAS_CHECKS >= IMP_USAGE
82
check_value_=111111111;
83
#endif
84
count_=0;
85
}
86
87
#ifndef _MSC_VER
88
template
<
class
R,
class
E>
89
friend
struct
internal::RefStuff;
90
#else
91
public
:
92
#endif // _MSC_VER
93
mutable
int
count_;
94
#if IMP_HAS_CHECKS >= IMP_USAGE
95
double
check_value_;
96
#endif
97
protected
:
98
RefCounted
(){init();}
99
// things right.
100
#ifdef _MSC_VER
101
public
:
102
#endif
103
// the virtual is not strictly needed but helps for getting
104
virtual
~
RefCounted
();
105
106
public
:
107
108
#ifndef IMP_DOXYGEN
109
// Return whether the object already been freed
110
bool
get_is_valid()
const
{
111
#if IMP_HAS_CHECKS == IMP_NONE
112
return
true
;
113
#else
114
return
static_cast<
int
>
(check_value_)==111111111;
115
#endif
116
}
117
118
void
show
(std::ostream &)
const
{};
119
120
std::string get_name()
const
{
return
"RefCounted"
;}
121
#endif
122
123
unsigned
int
get_ref_count()
const
{
124
return
count_;
125
}
126
127
static
unsigned
int
get_number_of_live_objects() {
128
// for debugging purposes only
129
return
live_objects_;
130
}
131
#endif // IMP_DOXYGEN
132
133
bool
get_is_shared()
const
{
134
return
count_ > 1;
135
}
136
137
};
138
139
IMPBASE_END_NAMESPACE
140
141
#endif
/* IMPBASE_REF_COUNTED_H */