branch merge ns-3.3-RC2
authorCraig Dowell <craigdo@ee.washington.edu>
Fri, 05 Dec 2008 16:49:29 -0800
changeset 3988654eed5f3ad0
parent 3987 cfafbc337dbb
parent 3986 44d4f4d768dd
child 3989 5918a4bec9e2
branch merge
     1.1 --- a/doc/manual/manual.texi	Fri Dec 05 16:49:05 2008 -0800
     1.2 +++ b/doc/manual/manual.texi	Fri Dec 05 16:49:29 2008 -0800
     1.3 @@ -81,18 +81,21 @@
     1.4  * Random variables::
     1.5  * Callbacks::
     1.6  * Attributes::
     1.7 +* Object model::
     1.8  * RealTime::
     1.9 +* Emulation::
    1.10  * Packets::
    1.11  * Sockets APIs::
    1.12  * Node and Internet Stack::
    1.13  * TCP::
    1.14  * Routing overview::
    1.15 -* Troubleshooting
    1.16 +* Troubleshooting::
    1.17  @end menu
    1.18  
    1.19  @include random.texi
    1.20  @include callbacks.texi
    1.21  @include attributes.texi
    1.22 +@include objects.texi
    1.23  @include realtime.texi
    1.24  @include emulation.texi
    1.25  @include packets.texi
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/doc/manual/objects.texi	Fri Dec 05 16:49:29 2008 -0800
     2.3 @@ -0,0 +1,281 @@
     2.4 +@c ========================================================================
     2.5 +@c ns-3 Object model
     2.6 +@c ========================================================================
     2.7 +
     2.8 +@node Object model
     2.9 +@chapter Object model
    2.10 +
    2.11 +@command{ns-3} is fundamentally a C++ object system.  Objects can
    2.12 +be declared and instantiated as usual, per C++ rules.  ns-3 also
    2.13 +adds some features to traditional C++ objects, as described below,
    2.14 +to provide greater functionality and features.  This manual chapter
    2.15 +is intended to introduce the reader to the ns-3 object model.
    2.16 +
    2.17 +This section describes the C++ class design for ns-3 objects.  In brief,
    2.18 +several design patterns in use include classic object-oriented design
    2.19 +(polymorphic interfaces and implementations), separation of interface
    2.20 +and implementation, the non-virtual public interface design pattern,
    2.21 +an object aggregation facility, and reference counting
    2.22 +for memory management.  Those familiar with component models such
    2.23 +as COM or Bonobo will recognize elements of the design in the 
    2.24 +ns-3 object aggregation model, although
    2.25 +the ns-3 design is not strictly in accordance with either.
    2.26 +
    2.27 +@node Object-oriented behavior
    2.28 +@section Object-oriented behavior
    2.29 +
    2.30 +C++ objects, in general, provide common object-oriented capabilities 
    2.31 +(abstraction, encapsulation, inheritance, and polymorphism) that are part 
    2.32 +of classic object-oriented design.  ns-3 objects make use of these 
    2.33 +properties; for instance:
    2.34 +
    2.35 +@verbatim
    2.36 +class Address
    2.37 +{
    2.38 +public:
    2.39 +  Address ();
    2.40 +  Address (uint8_t type, const uint8_t *buffer, uint8_t len);
    2.41 +  Address (const Address & address);
    2.42 +  Address &operator = (const Address &address);
    2.43 +  ...
    2.44 +private:
    2.45 +  uint8_t m_type;
    2.46 +  uint8_t m_len;
    2.47 +  ...
    2.48 +};
    2.49 +@end verbatim
    2.50 +
    2.51 +@node Object base classes
    2.52 +@section Object base classes
    2.53 +
    2.54 +There are two special base classes used in ns-3.  Classes that inherit
    2.55 +from these base classes can instantiate objects with special properties.
    2.56 +These base classes are:
    2.57 +@itemize @bullet
    2.58 +@item @code{class Object}
    2.59 +@item @code{class ObjectBase}
    2.60 +@item @code{class RefCountBase}
    2.61 +@end itemize
    2.62 +It is not required that ns-3 objects inherit from these class, but 
    2.63 +those that do get special properties.  Classes deriving from 
    2.64 +@code{class Object} get the following properties.
    2.65 +@itemize @bullet
    2.66 +@item the ns-3 type and attribute system (see @ref{Attributes})
    2.67 +@item a smart-pointer reference counting system (class Ptr)
    2.68 +@item an object aggregation system
    2.69 +@end itemize
    2.70 +
    2.71 +Classes that derive from @code{class ObjectBase} get the first two
    2.72 +properties above, but do not get smart pointers.  Classes that
    2.73 +derive from @code{class RefCountBase} get only the smart-pointer
    2.74 +reference counting system.
    2.75 +
    2.76 +In practice, @code{class Object} is the variant of the three above that
    2.77 +the ns-3 developer will most commonly encounter.
    2.78 +
    2.79 +@node Memory management and class Ptr
    2.80 +@section Memory management and class Ptr
    2.81 +
    2.82 +Memory management in a C++ program is a complex process, and is
    2.83 +often done incorrectly or inconsistently.  We have settled on 
    2.84 +a reference counting design described as follows.
    2.85 +
    2.86 +All objects using reference counting maintain an internal reference
    2.87 +count to determine when an object can safely delete itself.  
    2.88 +Each time that a pointer is obtained to an interface, the object's
    2.89 +reference count is incremented by calling @code{Ref()}.
    2.90 +It is the obligation of the
    2.91 +user of the pointer to explicitly @code{Unref()} the pointer when done.
    2.92 +When the reference count falls to zero, the object is deleted.
    2.93 +
    2.94 +@itemize @bullet
    2.95 +@item When the client code obtains a pointer from the object itself
    2.96 +through object creation, or via QueryInterface, it does not have
    2.97 +to increment the reference count.   
    2.98 +@item When client code obtains a pointer from another source (e.g.,
    2.99 +copying a pointer) it must call @code{Ref()} to increment the
   2.100 +reference count.
   2.101 +@item All users of the object pointer must call @code{Unref()} to
   2.102 +release the reference.
   2.103 +@end itemize
   2.104 +
   2.105 +The burden for calling @code{Unref()} is somewhat relieved by the
   2.106 +use of the reference counting smart pointer class described below. 
   2.107 +
   2.108 +Users using a low-level API who wish to explicitly allocate
   2.109 +non-reference-counted objects on the heap, using operator new, 
   2.110 +are responsible for deleting such objects.
   2.111 +
   2.112 +Packet objects are handled differently (without reference
   2.113 +counting); their design is described in @ref{Packets}.
   2.114 +
   2.115 +@subsection Reference counting smart pointer (Ptr)
   2.116 +
   2.117 +Calling @code{Ref()} and @code{Unref()} all the time would be cumbersome,
   2.118 +so ns-3 provides a smart pointer @code{class Ptr} similar to 
   2.119 +@code{Boost::intrusive_ptr}.
   2.120 +This smart-pointer class assumes that the underlying type provides 
   2.121 +a pair of Ref and Unref methods that are expected to increment and 
   2.122 +decrement the internal refcount of the object instance.  
   2.123 +
   2.124 +This implementation allows you to manipulate the smart pointer
   2.125 +as if it was a normal pointer: you can compare it with zero,
   2.126 +compare it against other pointers, assign zero to it, etc.
   2.127 +
   2.128 +It is possible to extract the raw pointer from this
   2.129 +smart pointer with the GetPointer and PeekPointer methods.
   2.130 +
   2.131 +If you want to store a newed object into a smart pointer,
   2.132 +we recommend you to use the CreateObject template functions
   2.133 +to create the object and store it in a smart pointer to avoid
   2.134 +memory leaks. These functions are really small convenience
   2.135 +functions and their goal is just is save you a small
   2.136 +bit of typing.
   2.137 +
   2.138 +@node CreateObject and Create
   2.139 +@subsection CreateObject and Create
   2.140 +
   2.141 +Objects in C++ may be statically, dynamically, or automatically created.
   2.142 +This holds true for ns-3 also, but some objects in the system 
   2.143 +have some additional frameworks
   2.144 +available.  Specifically, reference counted objects are usually
   2.145 +allocated using a templated Create or CreateObject method, as follows.
   2.146 +
   2.147 +For objects deriving from @code{class Object}:
   2.148 +@verbatim
   2.149 + Ptr<WifiNetDevice> device = CreateObject<WifiNetDevice> ();
   2.150 +@end verbatim
   2.151 +
   2.152 +For objects deriving from @code{class RefCountBase}, or other
   2.153 +objects that support usage of smart pointer (e.g., the ns-3 Packet class),
   2.154 +a templated helper function is available and recommended to be used:
   2.155 +@verbatim
   2.156 +  ns3::Ptr<B> b = ns3::Create<B> ();
   2.157 +@end verbatim  
   2.158 +This is simply a wrapper around operator new that correctly handles
   2.159 +the reference counting system.
   2.160 +
   2.161 +@node Aggregation
   2.162 +@subsection Aggregation
   2.163 +
   2.164 +The ns-3 object aggregation system is motivated in strong part by 
   2.165 +a recognition that a common use case for ns-2 has been the use of 
   2.166 +inheritance and polymorphism to extend protocol models.  For instance, 
   2.167 +specialized versions of TCP such as RenoTcpAgent derive from (and override 
   2.168 +functions from) class TcpAgent.  
   2.169 +
   2.170 +However, two problems that have arisen in the ns-2 model are downcasts
   2.171 +and ``weak base class.''  Downcasting refers to the procedure of using
   2.172 +a base class pointer to an object and querying it at run time to
   2.173 +find out type information, used to explicitly cast the pointer to 
   2.174 +a subclass pointer so that the subclass API can be used.
   2.175 +Weak base class refers to the problems that arise when a class
   2.176 +cannot be effectively reused (derived from) because it lacks necessary
   2.177 +functionality, leading the developer to have to modify the
   2.178 +base class and causing proliferation of base class API calls, some
   2.179 +of which may not be semantically correct for all subclasses.
   2.180 +
   2.181 +ns-3 is using a version of the query interface design pattern
   2.182 +to avoid these problems.  This design is based on elements of the 
   2.183 +@uref{http://en.wikipedia.org/wiki/Component_Object_Model,,Component Object Model} 
   2.184 +and @uref{http://en.wikipedia.org/wiki/Bonobo_(component_model),,GNOME Bonobo}
   2.185 +although full binary-level compatibility of replaceable components
   2.186 +is not supported and we have tried to simplify the syntax and impact
   2.187 +on model developers.  
   2.188 +
   2.189 +@subsubsection Aggregation example
   2.190 +
   2.191 +@code{class Node} is a good example of the use of aggregation in ns-3.
   2.192 +Note that there are not derived classes of Nodes in ns-3 such as
   2.193 +class InternetNode.  Instead, components (protocols) are aggregated to 
   2.194 +a node.  Let's look at how some Ipv4 protocols are added to a node.
   2.195 +
   2.196 +@verbatim
   2.197 +static void
   2.198 +AddIpv4Stack(Ptr<Node> node)
   2.199 +{
   2.200 +  Ptr<Ipv4L3Protocol> ipv4 = CreateObject<Ipv4L3Protocol> ();
   2.201 +  ipv4->SetNode (node);
   2.202 +  node->AggregateObject (ipv4);
   2.203 +  Ptr<Ipv4Impl> ipv4Impl = CreateObject<Ipv4Impl> ();
   2.204 +  ipv4Impl->SetIpv4 (ipv4);
   2.205 +  node->AggregateObject (ipv4Impl);
   2.206 +}
   2.207 +@end verbatim
   2.208 +
   2.209 +Note that the Ipv4 protocols are created using @code{CreateObject()}.  
   2.210 +Then, they are aggregated to the node.  In this manner, the Node base
   2.211 +class does not need to be edited to allow users with a base class Node
   2.212 +pointer to access the Ipv4 interface; users may ask the node for a pointer
   2.213 +to its Ipv4 interface at runtime.  How this is done is seen in the next
   2.214 +subsection.
   2.215 +
   2.216 +@subsubsection GetObject example
   2.217 +GetObject is a type-safe way to achieve a safe downcasting 
   2.218 +and to allow interfaces to be found on an object.  
   2.219 +
   2.220 +Consider a node pointer @code{m_node} that points to a Node object 
   2.221 +with an implementation of IPv4.  The client code wishes to configure
   2.222 +a default route.  To do so, it must access an object within
   2.223 +the node that has an interface to the IP forwarding configuration.
   2.224 +It performs the following:
   2.225 +@verbatim
   2.226 +  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
   2.227 +@end verbatim
   2.228 +
   2.229 +If the node in fact does not have an Ipv4 object aggregated to it, then
   2.230 +the method will return null.  Therefore, it is good practice to check
   2.231 +the return value from such a function call.  If successful, the user can
   2.232 +now use the Ptr to the Ipv4 object that was previously aggregated to
   2.233 +the node.
   2.234 +
   2.235 +@subsubsection Summary
   2.236 +To summarize, two benefits that we expect to leverage from this are as follows:
   2.237 +@itemize @bullet
   2.238 +@item @strong{Encapsulation:} By separating interface from implementation, 
   2.239 +it permits
   2.240 +implementors to replace elements of the protocol stack while remaining
   2.241 +compliant with client code that supports the same interface.  For
   2.242 +example, one type of node may include native ns-3 models of protocols,
   2.243 +while another may be a port of a Linux stack, and both may be accessed
   2.244 +by the same base class node pointer.
   2.245 +@item @strong{Aggregation:} AggregateObject allows for aggregation of 
   2.246 +objects at
   2.247 +run time.  For instance, an existing Node object may have an ``Energy Model''
   2.248 +object aggregated to it at run time (without modifying
   2.249 +and recompiling the node class).  An existing model (such as a wireless
   2.250 +net device) can then later "GetObject" for the energy model and act 
   2.251 +appropriately if the interface has been either built in to the underlying
   2.252 +Node object or aggregated to it at run time.
   2.253 +@end itemize
   2.254 +
   2.255 +We hope that this mode of programming will require much less 
   2.256 +need for developers to modify the @code base classes or libraries.
   2.257 +
   2.258 +@node Downcasting
   2.259 +@section Downcasting
   2.260 +
   2.261 +A question that has arisen several times is, "If I have a base class
   2.262 +pointer (Ptr) to an object and I want the derived class pointer, should
   2.263 +I downcast (via C++ dynamic cast) to get the derived pointer, or should
   2.264 +I use the object aggregation system to @code{GetObject<> ()} to find
   2.265 +a Ptr to the interface to the subclass API?"
   2.266 +
   2.267 +The answer to this is that in many situations, both techniques will work.
   2.268 +ns-3 provides a templated function for making the syntax of Object
   2.269 +dynamic casting much more user friendly:
   2.270 +@verbatim
   2.271 +template <typename T1, typename T2>
   2.272 +Ptr<T1>
   2.273 +DynamicCast (Ptr<T2> const&p)
   2.274 +{
   2.275 +  return Ptr<T1> (dynamic_cast<T1 *> (PeekPointer (p)));
   2.276 +}
   2.277 +@end verbatim
   2.278 +
   2.279 +DynamicCast works when the programmer has a base type pointer and is
   2.280 +testing against a subclass pointer.  GetObject works when looking for
   2.281 +different objects aggregated, but also works with subclasses, in the same
   2.282 +way as DynamicCast.  If unsure, the programmer should use GetObject, as it
   2.283 +works in all cases.   If the programmer knows the class hierarchy of the
   2.284 +object under consideration, it is more direct to just use DynamicCast.