In ns3, an object can be created according to the TypeId in the object. The cc file of each object has such a macro NS_OBJECT_ENSURE_REGISTERED to register the object. The content of this macro:
#define NS_OBJECT_ENSURE_REGISTERED(type) \
static struct X ## type ## RegistrationClass \
{ \
X ## type ## RegistrationClass () { \
ns3::TypeId tid = type::GetTypeId (); \
tid.GetParent (); \
} \
} x_ ## type ## RegistrationVariable
type::GetTypeId(); Executes the static function GetTypeId() implemented in each class . Take the Application of PacketSink as an example, its GetTypeId function:
TypeId
PacketSink::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::PacketSink")
.SetParent<Application> ()
.AddConstructor<PacketSink> ()
.AddAttribute ("Local", "The Address on which to Bind the rx socket.",
AddressValue (),
MakeAddressAccessor (&PacketSink::m_local),
MakeAddressChecker ())
.AddAttribute ("Protocol", "The type id of the protocol to use for the rx socket.",
TypeIdValue (UdpSocketFactory::GetTypeId ()),
MakeTypeIdAccessor (&PacketSink::m_tid),
MakeTypeIdChecker ())
.AddTraceSource ("Rx", "A packet has been received",
MakeTraceSourceAccessor (&PacketSink::m_rxTrace))
;
return tid;
}
AddConstructor<PacketSink>
Register constructors for object types. This associates the TypeID of a class with the instantiation of the class.
TypeId::AddConstructor (void)
{
struct Maker {
static ObjectBase * Create () {
ObjectBase * base = new T ();
return base;
}
};
Callback<ObjectBase *> cb = MakeCallback (&Maker::Create);
DoAddConstructor (cb);
return *this;
}
So I see that PacketSinkHelper sets the TypeID of ns3::PacketSink to ObjectFactory.
PacketSinkHelper::PacketSinkHelper (std::string protocol, Address address)
{
m_factory.SetTypeId ("ns3::PacketSink");
m_factory.Set ("Protocol", StringValue (protocol));//PacketSink中的属性
m_factory.Set ("Local", AddressValue (address));
}
On the surface, it is seen that Application is instantiated in PacketSinkHelper, but since the TypeID of ns3::PacketSink is registered before, the subclass of PacketSink is finally instantiated.
Ptr<Application> app = m_factory.Create<Application>