[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ns-3 is fundamentally a C++ object-based system. By this we mean that new C++ classes (types) can be declared, defined, and subclassed as usual.
Many ns-3 objects inherit from the ns3::Object
base class. These
objects have some additional properties that we exploit for
organizing the system and improving the memory management
of our objects:
ns-3 objects that use the attribute system derive from either
ns3::Object
or ns3::ObjectBase
. Most ns-3 objects
we will discuss derive from ns3::Object
, but a few that
are outside the smart pointer memory management framework derive
from ns3::ObjectBase
.
Let’s review a couple of properties of these objects.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As introduced in the ns-3 tutorial, ns-3 objects are memory managed by a
reference counting smart pointer implementation, class ns3::Ptr
.
Smart pointers are used extensively in the ns-3 APIs, to avoid passing references to heap-allocated objects that may cause memory leaks. For most basic usage (syntax), treat a smart pointer like a regular pointer:
Ptr<WifiNetDevice> nd = ...; nd->CallSomeFunction (); // etc.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As we discussed above in Memory management and class Ptr,
at the lowest-level API, objects of type ns3::Object
are
not instantiated using operator new
as usual but instead by
a templated function called CreateObject()
.
A typical way to create such an object is as follows:
Ptr<WifiNetDevice> nd = CreateObject<WifiNetDevice> ();
You can think of this as being functionally equivalent to:
WifiNetDevice* nd = new WifiNetDevice ();
Objects that derive from ns3::Object
must be allocated
on the heap using CreateObject(). Those deriving from
ns3::ObjectBase
, such as ns-3 helper functions and packet
headers and trailers, can be allocated on the stack.
In some scripts, you may not see a lot of CreateObject() calls in the code; this is because there are some helper objects in effect that are doing the CreateObject()s for you.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ns-3 classes that derive from class ns3::Object can include
a metadata class called TypeId
that records meta-information
about the class, for use in the object aggregation and component
manager systems:
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Putting all of these concepts together, let’s look at a specific
example: class ns3::Node
.
The public header file node.h has a declaration that includes a static GetTypeId function call:
class Node : public Object { public: static TypeId GetTypeId (void); ...
This is defined in the node.cc file as follows:
|
Consider the TypeId of an ns-3 Object
class as an extended form of run
time type information (RTTI). The C++ language includes a simple kind of RTTI
in order to support dynamic_cast
and typeid
operators.
The “.SetParent<Object> ()
” call in the declaration above is used in
conjunction with our object aggregation mechanisms to allow safe up- and
down-casting in inheritance trees during GetObject
.
The “.AddConstructor<Node> ()
” call is used in conjunction with our
abstract object factory mechanisms to allow us to construct C++ objects without
forcing a user to know the concrete class of the object she is building.
The three calls to “.AddAttribute
” associate a given string with a
strongly typed value in the class. Notice that you must provide a help string
which may be displayed, for example, via command line processors. Each
Attribute
is associated with mechanisms for accessing the underlying
member variable in the object (for example, MakeUintegerAccessor
tells
the generic Attribute
code how to get to the node ID above). There are
also “Checker” methods which are used to validate values.
When users want to create Nodes, they will usually call some form of
CreateObject
,
Ptr<Node> n = CreateObject<Node> ();
or more abstractly, using an object factory, you can create a Node
object
without even knowing the concrete C++ type
ObjectFactory factory; const std::string typeId = "ns3::Node''; factory.SetTypeId (typeId); Ptr<Object> node = factory.Create <Object> ();
Both of these methods result in fully initialized attributes being available
in the resulting Object
instances.
We next discuss how attributes (values associated with member variables or functions of the class) are plumbed into the above TypeId.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated on August 20, 2010 using texi2html 1.82.