NS3中TypeId的机制与作用

来源:互联网 发布:mac 开机 问号 编辑:程序博客网 时间:2024/05/22 17:06

图1

在NS3中我们可以通过直接继承类Object来使用TypeId、属性系统和智能指针的功能。具体继承关系如图1所示:

在NS3中为了系统的使用方便,通过类TypeId为每个类都注册了一个唯一的标识,类名与标识一一对应,那么就可以直接用这个标识去找到对应的类去实例化对象。下面我们就以类Node为例,看看NS3中的TypeId是如何使用的。如果新类想使用以上三种功能,就必须继承类Object并且实现以下函数:来注册这个唯一的表示以及设置与构造相关的参数,这个标识对于用户来说指的是这个新类的类名(字符串)。以Node为例:


图2

        首先,在图2的52行中,实例化了一个TypeId,并且实现了类Node与字符串“ns3::Node”的一一对应关系。到底是怎么实现的呢?不着急,我们慢慢来看。NS3中用一个特殊的类去管理这些一一对应的关系以及与构造类有关的信息。管理者一般只有一个,不错,Ta就是一个非常重要的IidManager。它是用来管理所有NS3中与TypeId相关的操作的。

       IidManager的继承关系为NonCopyable->Singleton->IidManager,其中NonCopyable为一个不可复制的类,它的拷贝构造函数与赋值构造函数均为私有类型。而Singleton是通过私有继承NonCopyable,因此成为唯一的单例模式。可以唯一通过Get()函数来获取Singleton的唯一的不可复制的实例。IidManager继承于Singleton<IidManager>,因此通过IidManager::Get()来获取整个NS3中不可复制的单例IidManager。那么单例IidManager到底做了什么呢?不着急我们继续:IidManager一个很重要的功能就是通过一个Hasher函数来实现从字符串到整数(hash)的一一对应关系的,有兴趣的小伙伴可以看看它是怎样实现,一个字符串唯一对应一个整数的。找到了这种对应关系,那么与类的构造有关的信息怎么存储呢?相信大家都会想到用一个结构体去存放。是的,请看下图:


       这个结构体存放了我们前面所说的对应关系以及与构造有关的信息。作为管理者不仅仅只管理一个员工,是的,IidManager中会有一个IidInformation类型的vector (m_information),存放所有的注册的类的相关信息。此时,我们如果想通过前面注册的唯一的标识(字符串,name)去访问m_information中的某个元素怎么办呢?通过下标去访问?那么是下标是多少?此时,我们就会想到,如果把name和对应的IidInformation下标绑定到一起那么访问就变得很easy了。的确,NS3也时这样做的,用一个map<name, index>实现。同样,还提供了一个map<hash, index>方便内部访问。到此时,我们可以随意的拿到我们注册的那个类的信息了。

         但是,到现在我们能拿到的只有类的对应IidInformation。其中,其他成员均未赋值。不着急,图2 52行,53行,分别设置了父类(通过父类可以追溯到基类)以及此类所属的group。图2 55行,为IidInformation填写了最为重要的一个成员(此类的构造函数)。其原理是,将此类的构造函数作为回调函数复制给了IidInformation中的Callback<ObjectBase*>constructor,用通用的父类ObjectBase的指针去存放子类的构造函数。图 2 56~73行为IidInformation 的成员std::vector<structTypeId::AttributeInformation>  attributes添加一些必要的属性和绑定,用于实例化对象时的赋值。到此处所有与TypeId有关大部分都已经介绍完了。

         那么TypeId的有什么作用呢?

1.      通过TypeId和Attribute的结合使用,使得代码的封装性更强,脚本配置更为方便。

2.      在进行类的实例化的时候尤为重要,在这里我们讨论两种实例化方法:

第一种:CreateObject<Node>(),这种方法一般是构造所有变量均为默认值的类。

第二种:通过ObjectFactory的方法Create来构造,此方法结合工厂机制,直接通过类的TypeId以及用户配置的属性集合AttributeConstructionList,来实例化用户需要的对象。

以上两种方法在构造的过程中,由于每个TypeId只管理当前类的可变成员变量,所以在赋初值(包括默认值,或者通过脚本修改的值,或者环境变量里面获取的值)的时候,从子类一直tree back到ObjectBase为止。最后封装成为智能指针返回。

另外,属性系统更偏向于使用而智能指针相对比较简单易懂,与c++中的智能指针类似,后续可能会补上。








原创粉丝点击