当前位置: 首页 > 工具软件 > iTcl > 使用案例 >

ITCL初步

归明诚
2023-12-01
2006-1-16开始有了时间学习Tcl,在熟悉了这门语言的基本语法后,很快就转向了它的面向对象的扩展Incr Tcl。
ITCL模拟了C++的面向对象特征,支持单继承和多继承(多态,目前还没有发现有关这方面的资料)。
首先从TCL背景知识入手介绍一个很重要的概念,其实这个概念从语言名称就已经体现了:TOOL Command Language,工具命令语言,它是一种脚本,就象VBA语言提供的把各种对象粘合在一起功能,在内存管理方面,脚本中的所有变量在统一名字空间中必须唯一(从Tcl引入名字空间这个概念推断,Tcl把变量保存到为平板型的名值对中,通过变量名称查找变量值)由于这个要求,使在使用这个语言的面向对象特征的过程中,遇到了麻烦。
本文只是记录解决问题的一个过程:
问题是:
首先编写两个itcl类:
package require Itcl
namespace import itcl::*
 
class Person {
       variable m_name
       variable m_sex
       variable m_age
       #constructor {} {
             
       #}
       constructor {name sex age} {
              set m_name name
              set m_sex sex
              set m_age age
              puts "create person $this"
       }
       destructor {
              puts "destroy object $this"
       }
}
 
class Family {
       variable m_father
       variable m_mother
       variable m_sister
       variable m_brothor
       constructor {father mother} {
              set m_father father
              set m_mother mothor
              set m_sister [Person m_sister "mary" "female" 22]
              set m_brother [Person m_brother "john" "male" 19]
       }
}
 
首先,声明了一个类Person,然后在Family类中使用这个类:
在Family类中实例化一个Person对象并赋值给m_sister。
现在就可以打开一个tkcon控制台,把以上代码复制进来后,接下来的操作出了问题:
实例化第一个Family对象,成功,而声明第二个的时候,问题如下:
按照面向对象思想,Family类中的变量都是实例变量(而不是静态变量),一个类的多个实例就拥有多个实例变量,而目前这个错误显示,Itcl不能够很好的实现这个问题。
command "m_sister" already exists in namespace "::Family"
实际上,针对这个问题,Itcl提供了一个办法,那就是使用#auto机制。示例如下:
set m_brother [Person #auto "john" "male" 19]   
#auto可以生成随机的实例名字,保证不会重复,然后把这个变量使用命令置换,置换给变量m_brother.
重写上面的Family类如下:
 
class Family {
       variable m_father
       variable m_mother
       variable m_sister
       variable m_brothor
       constructor {father mother} {
              set m_father father
              set m_mother mothor
              set m_sister [Person #auto "mary" "female" 22]
              set m_brother [Person #auto "john" "male" 19]
       }
}
修改这个类:
delete class Family
复制上面的代码进入tkcon后,创建几个该类的实例如下:
 
问题得到了解决。
删除对象的方法:
delete object h3
 
我们在项目中还用到了Tcl中的图:
::struct::graph是一个结构,它被应用在类中,在类被进行第二个实例化时也碰到了这个问题。由于#auto机制不适用于结构,所以自己写了一个静态类,借此机会描述一下Itcl的静态类。
这个有一个静态成员和一个静态函数,该函数提供一个唯一名字。
class CAuto {
       public common count 0
       proc getName {} {
        incr count
              return [concat "obj" $count]
       }
}
其中的common声明静态变量,proc用在类中表示声明静态成员函数。
使用如下:
set m_lnkseg [::struct::graph CTool::GetName]
如此也解决了问题。
以上解决办法,从根本上说是由于tcl的变量名称可以是单词符号,也可以是变量的变量,即解释执行的脚本语言。这种情况放在象C++、Java等语言中是无法走通的。
 类似资料: