doc/manual/source/object-model.rst
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--
Rescan wifi's bindings and fix some paths in the documentation
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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.