author | Mitch Watrous <watrous@u.washington.edu> |
Mon, 09 May 2011 18:04:52 -0700 | |
changeset 7145 | a925e518220b |
parent 6742 | a1759a95842c |
child 7572 | 45789a380d6a |
permissions | -rw-r--r-- |
6742
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
1 |
.. include:: replace.txt |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
2 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
3 |
Object model |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
4 |
------------ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
5 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
6 |
|ns3| is fundamentally a C++ object system. Objects can be declared and |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
7 |
instantiated as usual, per C++ rules. |ns3| also adds some features to |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
8 |
traditional C++ objects, as described below, to provide greater functionality |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
9 |
and features. This manual chapter is intended to introduce the reader to the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
10 |
|ns3| object model. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
11 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
12 |
This section describes the C++ class design for |ns3| objects. In brief, |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
13 |
several design patterns in use include classic object-oriented design |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
14 |
(polymorphic interfaces and implementations), separation of interface and |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
15 |
implementation, the non-virtual public interface design pattern, an object |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
16 |
aggregation facility, and reference counting for memory management. Those |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
17 |
familiar with component models such as COM or Bonobo will recognize elements of |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
18 |
the design in the |ns3| object aggregation model, although the |ns3| design is |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
19 |
not strictly in accordance with either. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
20 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
21 |
Object-oriented behavior |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
22 |
************************ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
23 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
24 |
C++ objects, in general, provide common object-oriented capabilities |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
25 |
(abstraction, encapsulation, inheritance, and polymorphism) that are part |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
26 |
of classic object-oriented design. |ns3| objects make use of these |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
27 |
properties; for instance::: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
28 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
29 |
class Address |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
30 |
{ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
31 |
public: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
32 |
Address (); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
33 |
Address (uint8_t type, const uint8_t *buffer, uint8_t len); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
34 |
Address (const Address & address); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
35 |
Address &operator = (const Address &address); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
36 |
... |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
37 |
private: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
38 |
uint8_t m_type; |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
39 |
uint8_t m_len; |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
40 |
... |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
41 |
}; |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
42 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
43 |
Object base classes |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
44 |
******************* |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
45 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
46 |
There are three special base classes used in |ns3|. Classes that inherit |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
47 |
from these base classes can instantiate objects with special properties. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
48 |
These base classes are: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
49 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
50 |
* class :cpp:class:`Object` |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
51 |
* class :cpp:class:`ObjectBase` |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
52 |
* class :cpp:class:`SimpleRefCount` |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
53 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
54 |
It is not required that |ns3| objects inherit from these class, but |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
55 |
those that do get special properties. Classes deriving from |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
56 |
class :cpp:class:`Object` get the following properties. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
57 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
58 |
* the |ns3| type and attribute system (see :ref:`Attributes`) |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
59 |
* an object aggregation system |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
60 |
* a smart-pointer reference counting system (class Ptr) |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
61 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
62 |
Classes that derive from class :cpp:class:`ObjectBase` get the first two |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
63 |
properties above, but do not get smart pointers. Classes that derive from class |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
64 |
:cpp:class:`SimpleRefCount`: get only the smart-pointer reference counting |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
65 |
system. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
66 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
67 |
In practice, class :cpp:class:`Object` is the variant of the three above that |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
68 |
the |ns3| developer will most commonly encounter. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
69 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
70 |
Memory management and class Ptr |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
71 |
******************************* |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
72 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
73 |
Memory management in a C++ program is a complex process, and is often done |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
74 |
incorrectly or inconsistently. We have settled on a reference counting design |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
75 |
described as follows. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
76 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
77 |
All objects using reference counting maintain an internal reference count to |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
78 |
determine when an object can safely delete itself. Each time that a pointer is |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
79 |
obtained to an interface, the object's reference count is incremented by calling |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
80 |
``Ref()``. It is the obligation of the user of the pointer to explicitly |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
81 |
``Unref()`` the pointer when done. When the reference count falls to zero, the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
82 |
object is deleted. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
83 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
84 |
* When the client code obtains a pointer from the object itself through object |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
85 |
creation, or via GetObject, it does not have to increment the reference count. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
86 |
* When client code obtains a pointer from another source (e.g., copying a |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
87 |
pointer) it must call ``Ref()`` to increment the reference count. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
88 |
* All users of the object pointer must call ``Unref()`` to release the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
89 |
reference. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
90 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
91 |
The burden for calling :cpp:func:`Unref()` is somewhat relieved by the use of |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
92 |
the reference counting smart pointer class described below. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
93 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
94 |
Users using a low-level API who wish to explicitly allocate |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
95 |
non-reference-counted objects on the heap, using operator new, are responsible |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
96 |
for deleting such objects. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
97 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
98 |
Reference counting smart pointer (Ptr) |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
99 |
++++++++++++++++++++++++++++++++++++++ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
100 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
101 |
Calling ``Ref()`` and ``Unref()`` all the time would be cumbersome, so |ns3| |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
102 |
provides a smart pointer class :cpp:class:`Ptr` similar to |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
103 |
:cpp:class:`Boost::intrusive_ptr`. This smart-pointer class assumes that the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
104 |
underlying type provides a pair of ``Ref`` and ``Unref`` methods that are |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
105 |
expected to increment and decrement the internal refcount of the object |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
106 |
instance. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
107 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
108 |
This implementation allows you to manipulate the smart pointer as if it was a |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
109 |
normal pointer: you can compare it with zero, compare it against other pointers, |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
110 |
assign zero to it, etc. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
111 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
112 |
It is possible to extract the raw pointer from this smart pointer with the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
113 |
:cpp:func:`GetPointer` and :cpp:func:`PeekPointer` methods. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
114 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
115 |
If you want to store a newed object into a smart pointer, we recommend you to |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
116 |
use the CreateObject template functions to create the object and store it in a |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
117 |
smart pointer to avoid memory leaks. These functions are really small |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
118 |
convenience functions and their goal is just to save you a small bit of typing. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
119 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
120 |
CreateObject and Create |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
121 |
+++++++++++++++++++++++ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
122 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
123 |
Objects in C++ may be statically, dynamically, or automatically created. This |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
124 |
holds true for |ns3| also, but some objects in the system have some additional |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
125 |
frameworks available. Specifically, reference counted objects are usually |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
126 |
allocated using a templated Create or CreateObject method, as follows. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
127 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
128 |
For objects deriving from class :cpp:class:`Object`::: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
129 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
130 |
Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> (); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
131 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
132 |
Please do not create such objects using ``operator new``; create them using |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
133 |
:cpp:func:`CreateObject()` instead. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
134 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
135 |
For objects deriving from class :cpp:class:`SimpleRefCount`, or other objects |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
136 |
that support usage of the smart pointer class, a templated helper function is |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
137 |
available and recommended to be used::: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
138 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
139 |
Ptr<B> b = Create<B> (); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
140 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
141 |
This is simply a wrapper around operator new that correctly handles the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
142 |
reference counting system. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
143 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
144 |
In summary, use ``Create<B>`` if B is not an object but just uses reference |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
145 |
counting (e.g. :cpp:class:`Packet`), and use ``CreateObject<B>`` if B derives |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
146 |
from :cpp:class:`ns3::Object`. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
147 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
148 |
Aggregation |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
149 |
+++++++++++ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
150 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
151 |
The |ns3| object aggregation system is motivated in strong part by a recognition |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
152 |
that a common use case for |ns2| has been the use of inheritance and |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
153 |
polymorphism to extend protocol models. For instance, specialized versions of |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
154 |
TCP such as RenoTcpAgent derive from (and override functions from) class |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
155 |
TcpAgent. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
156 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
157 |
However, two problems that have arisen in the |ns2| model are downcasts and |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
158 |
"weak base class." Downcasting refers to the procedure of using a base class |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
159 |
pointer to an object and querying it at run time to find out type information, |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
160 |
used to explicitly cast the pointer to a subclass pointer so that the subclass |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
161 |
API can be used. Weak base class refers to the problems that arise when a class |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
162 |
cannot be effectively reused (derived from) because it lacks necessary |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
163 |
functionality, leading the developer to have to modify the base class and |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
164 |
causing proliferation of base class API calls, some of which may not be |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
165 |
semantically correct for all subclasses. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
166 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
167 |
|ns3| is using a version of the query interface design pattern to avoid these |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
168 |
problems. This design is based on elements of the `Component Object Model |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
169 |
<http://en.wikipedia.org/wiki/Component_Object_Model>`_ and `GNOME Bonobo |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
170 |
<http://en.wikipedia.org/wiki/Bonobo_(component_model)>`_ although full |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
171 |
binary-level compatibility of replaceable components is not supported and we |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
172 |
have tried to simplify the syntax and impact on model developers. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
173 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
174 |
Aggregation example |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
175 |
+++++++++++++++++++ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
176 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
177 |
:cpp:class:`Node` is a good example of the use of aggregation in |ns3|. Note |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
178 |
that there are not derived classes of Nodes in |ns3| such as class |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
179 |
:cpp:class:`InternetNode`. Instead, components (protocols) are aggregated to a |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
180 |
node. Let's look at how some Ipv4 protocols are added to a node.:: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
181 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
182 |
static void |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
183 |
AddIpv4Stack(Ptr<Node> node) |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
184 |
{ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
185 |
Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> (); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
186 |
ipv4->SetNode (node); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
187 |
node->AggregateObject (ipv4); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
188 |
Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> (); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
189 |
ipv4Impl->SetIpv4 (ipv4); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
190 |
node->AggregateObject (ipv4Impl); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
191 |
} |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
192 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
193 |
Note that the Ipv4 protocols are created using :cpp:func:`CreateObject()`. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
194 |
Then, they are aggregated to the node. In this manner, the Node base class does |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
195 |
not need to be edited to allow users with a base class Node pointer to access |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
196 |
the Ipv4 interface; users may ask the node for a pointer to its Ipv4 interface |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
197 |
at runtime. How the user asks the node is described in the next subsection. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
198 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
199 |
Note that it is a programming error to aggregate more than one object of the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
200 |
same type to an :cpp:class:`ns3::Object`. So, for instance, aggregation is not |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
201 |
an option for storing all of the active sockets of a node. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
202 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
203 |
GetObject example |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
204 |
+++++++++++++++++ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
205 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
206 |
GetObject is a type-safe way to achieve a safe downcasting and to allow |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
207 |
interfaces to be found on an object. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
208 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
209 |
Consider a node pointer ``m_node`` that points to a Node object that has an |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
210 |
implementation of IPv4 previously aggregated to it. The client code wishes to |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
211 |
configure a default route. To do so, it must access an object within the node |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
212 |
that has an interface to the IP forwarding configuration. It performs the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
213 |
following::: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
214 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
215 |
Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> (); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
216 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
217 |
If the node in fact does not have an Ipv4 object aggregated to it, then the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
218 |
method will return null. Therefore, it is good practice to check the return |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
219 |
value from such a function call. If successful, the user can now use the Ptr to |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
220 |
the Ipv4 object that was previously aggregated to the node. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
221 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
222 |
Another example of how one might use aggregation is to add optional models to |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
223 |
objects. For instance, an existing Node object may have an "Energy Model" object |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
224 |
aggregated to it at run time (without modifying and recompiling the node class). |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
225 |
An existing model (such as a wireless net device) can then later "GetObject" for |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
226 |
the energy model and act appropriately if the interface has been either built in |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
227 |
to the underlying Node object or aggregated to it at run time. However, other |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
228 |
nodes need not know anything about energy models. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
229 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
230 |
We hope that this mode of programming will require much less need for developers |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
231 |
to modify the base classes. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
232 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
233 |
Object factories |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
234 |
**************** |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
235 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
236 |
A common use case is to create lots of similarly configured objects. One can |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
237 |
repeatedly call :cpp:func:`CreateObject` but there is also a factory design |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
238 |
pattern in use in the |ns3| system. It is heavily used in the "helper" API. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
239 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
240 |
Class :cpp:class:`ObjectFactory` can be used to instantiate objects and to |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
241 |
configure the attributes on those objects:: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
242 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
243 |
void SetTypeId (TypeId tid); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
244 |
void Set (std::string name, const AttributeValue &value); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
245 |
Ptr<T> Create (void) const; |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
246 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
247 |
The first method allows one to use the |ns3| TypeId system to specify the type |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
248 |
of objects created. The second allows one to set attributes on the objects to be |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
249 |
created, and the third allows one to create the objects themselves. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
250 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
251 |
For example: :: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
252 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
253 |
ObjectFactory factory; |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
254 |
// Make this factory create objects of type FriisPropagationLossModel |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
255 |
factory.SetTypeId ("ns3::FriisPropagationLossModel") |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
256 |
// Make this factory object change a default value of an attribute, for |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
257 |
// subsequently created objects |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
258 |
factory.Set ("SystemLoss", DoubleValue (2.0)); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
259 |
// Create one such object |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
260 |
Ptr<Object> object = m_factory.Create (); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
261 |
factory.Set ("SystemLoss", DoubleValue (3.0)); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
262 |
// Create another object |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
263 |
Ptr<Object> object = m_factory.Create (); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
264 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
265 |
Downcasting |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
266 |
*********** |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
267 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
268 |
A question that has arisen several times is, "If I have a base class pointer |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
269 |
(Ptr) to an object and I want the derived class pointer, should I downcast (via |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
270 |
C++ dynamic cast) to get the derived pointer, or should I use the object |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
271 |
aggregation system to :cpp:func:`GetObject\<> ()` to find a Ptr to the interface |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
272 |
to the subclass API?" |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
273 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
274 |
The answer to this is that in many situations, both techniques will work. |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
275 |
|ns3| provides a templated function for making the syntax of Object |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
276 |
dynamic casting much more user friendly::: |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
277 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
278 |
template <typename T1, typename T2> |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
279 |
Ptr<T1> |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
280 |
DynamicCast (Ptr<T2> const&p) |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
281 |
{ |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
282 |
return Ptr<T1> (dynamic_cast<T1 *> (PeekPointer (p))); |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
283 |
} |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
284 |
|
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
285 |
DynamicCast works when the programmer has a base type pointer and is testing |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
286 |
against a subclass pointer. GetObject works when looking for different objects |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
287 |
aggregated, but also works with subclasses, in the same way as DynamicCast. If |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
288 |
unsure, the programmer should use GetObject, as it works in all cases. If the |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
289 |
programmer knows the class hierarchy of the object under consideration, it is |
a1759a95842c
convert manual to sphinx format
Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
parents:
diff
changeset
|
290 |
more direct to just use DynamicCast. |