NS2入门学习(五)之分裂对象模型和TclCL

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaojiewang1990/article/details/54425872

 TclCL其实就是连接C++与Otcl,实现两者的互相操作和两者之间类的对应.

NS中使用两种语言原因:

C++运行速度较快,是强制类型语言(进行严格的数据类型检查),容易实现复杂的数据类型和精确/复杂的算法。但是修改/debug和重新编译时间较长,所以适合完成网络协议等各种模拟环境的算法的实现。

Otcl运行速度慢,但是可以很方便的修改,不需要编译,而且不是强制类型的,适合用来做模拟的环境的配置。

以下情况使用Otcl:

对模拟场景的建立、配置、和模拟中只需要运行依次的程序;另一种时如果通过Otcl脚本操作已经存在的C++对象就能很方便的达到目的。

以下情况使用C++:

需要对一个数据流的每个分组进行处理的任何工作;如果你必须修改已存在的C++类的行为。

1、分裂对象模型之C++与Otcl对应关系和命名规则


NS 的构件都是由相互关联的两个类来实现,一个在C++中,一个在Otcl中,因此包含了如上图的一个C++类的层次结构和一个Otcl类的层次结构。主要功能通常在C++程序中实现,Otcl类则主要提供C++对象面向用户的配置接口。
每当实例化一个构件时,都会同时创建一个Otcl中的对象和一个对应的C++对象,并且两个对象可以互操作。如下图

类的命名规则:在分裂对象模型中,所有的c++类都是从TclObject一级级继承出来。所有的Otcl类都是从SplitObject一级级继承出来的。A/B/C/D是A/B/C的子类。“/”表示一级级的继承关系。

2、分裂对象模型之C++与Otcl之间的对象连接

TclObject和TclClass   

TclCL是通过TclObject和TclClass两个C++类,把Otcl类和C++类关联起来的。TclObject是所有编译类的基类,对应的SplitObject是所有解释类的基类。
创建和销毁TclObject:
在Otcl脚本中使用过程new{}和delete{},例如
set tcp1 {new Agent/TCP}
delete $tcpl
过程new{}首先创建出解释对象,然后会执行该对象的初始化实例过程init{},并把用户提供的参数传给它。在基类SplitObject的初始化实例过程中会通过 create-shadow方法创建对象在C++中的影像对象,此时该影像对象的构造函数将会被执行,其中通常会进行一些变量绑定工作。因此每个解释类都必须在初始化实例的过程中调用父类的初始化实例过程,以便最终能够执行到SplitObject的初始化实例的过程去创建影像对象。创建影像对象时将进行变量绑定,最好调用父类的初始化实例过程要先于当前类的初始化,以便绑定变量能够尽早被创建。
如果用户直接在C++中创建一个编译的TclObject,Otcl中的影像对象时不会被创建的。 因此在NS中禁止直接使用C++的new操作来创建编译对象。最终,在基类splitObject的销毁过程中将调用实例过程 delete-shadow,这将导致影像对象被析构。
create-shadow方法创建的影像对象属于C++中的哪个类,是由TclClass来确定的。TclClass是个纯虚类,从这个基类继承出来的类提供两个功能:1,构造与编译类对应的解释类结构 2,提供初始化新的TclObject的方法。每个从TclClass继承出来的类都和编译类结构中的一个TclObject的子类相关联,并能初始化所关联类的新的对象。
static class RenoTcpClass:public TclClass {
public:
        RenoTcpClass():TclClass("Agent/TCP/Reno"){}
        TclObject* create(int argc,const char*const *argv  )
         {return(new RenoTcpAgent());}
}class_reno;}
上面之定义了一个方法create,用以创建所关联的TclObject子类的实例。而在其构造函数中通过调用基类的构造函数TclClass("Agent/TCP/Reno")指定了其对应的解释类为Agent/TCP/Reno。这实际上是做了一种登记工作,以后每当在解释器中创建Agent/TCP/Reno时,create-shadow都会来调用这个RenoTcpClass的create函数,这样就创建出正确的影像对象,其实也起到了生命Otcl类的作用。
变量绑定:
NS 中解释对象的成员变量和编译对象的成员变量都访问相同的数据,且当任何一边的变量值改变时对应另一边的变量也改变为相同的值。绑定通常是在当该对象初始化时在编译对象的构造函数中建立的。
command()方法
要在Otcl对象中调用对应的C++对象的方法,NS是通过command()函数实现的,对于每一个TclObject,ns为其Otcl中的解释对象建立一个实例过程,cmd{}。过程cmd{}调用影像对象的方法command(),并将cmd{}的参数作為一个参数数组传递给command()方法。用户调用cmd{};可以通过显示的调用,即将进行的操作指定为第一个参数;或者可以隐式的调用,就像是存在一个和欲进行的操作同名的实例过程一样。

猜你喜欢

转载自blog.csdn.net/xiaojiewang1990/article/details/54425872
今日推荐