在 Tcloo 中创建一个类对象作为变量

create a class object as variable in Tcloo

提问人:JoshTitle 提问时间:1/27/2022 更新时间:1/27/2022 访问量:111

问:

我开始使用 tclOO。 我需要在我的主类 MainClass 中创建一个 Aclass 实例 anotherClassIns,如下所示:

oo:class create Aclass {
    variable num;
    constructor {argv} {
       set num [lindex $argv 0]
    }
}; #end of Aclass


oo:class create MainClass {
    variable anotherClassIns ; # this variable is another class's instance!
     
    constructor {argv} {
       Aclass create anotherClassIns {$argv};
    } 
} 

在 main 函数中,我创建了一个 MainClass 实例:

MainClass create Ins $argv

如果我想在 Aclass 中打印$num,我该怎么办?

谢谢。

哎呀 ,TCL公司

评论

0赞 Donal Fellows 1/27/2022
您未正确设置所属实例;它要么是(可能是本地的)命名,当你用 来命名时,要么是它是一个生成的名称(用 )命名,你把它存储在一个变量中。两者都有好处。这两种方法都返回新创建的对象的完全限定名称(除非元类出于某种原因覆盖了该名称;这仅适用于伪装成 Tk 小部件的类)。createnew

答:

1赞 Donal Fellows 1/27/2022 #1

TclOO 中的所有实例变量都具有全局可寻址的名称,因此它们可以与 Tcl 中期望这样命名的其他部分一起使用(尤其是 和 ,还有 Tk 的选项)。vwaittrace-textvariable

现在最简单的方法是创建一个访问器方法:

oo:class create Aclass {
    variable num
    constructor {argv} {
        set num [lindex $argv 0]
    }
    method num {} {
        return $num
    }
}
oo:class create MainClass {
    variable anotherClassIns
     
    constructor {argv} {
        set anotherClassIns [Aclass new {*}$argv]
    }
    destructor {} {
        # Assuming you're owning the inner instance
        $anotherClassIns destroy
    }

    method printTheValue {} {
        puts [$anotherClassIns num]
    }
} 

您还可以使用变量存在于命名空间中这一事实直接访问变量,并且可以使用以下命令查找该命名空间:info object namespace

    method printTheValue {} {
        # Probably easiest to do this
        namespace upvar [info object namespace $anotherClassIns] num v
        puts $v
    }

但这不适用于 8.7 的私有变量,因为这些变量的名称被篡改,外部代码绝对无法访问。在这种情况下,您需要提供对其内部的访问;从字面上看,这就是私有变量的意义所在。的方法可以帮助那里;默认情况下,它不会公开,但它可以通过 在内部使用 ,您可以通过定义为类甚至实例公开它。Aclassvarnameoo::objectmyexport

# Probably at object creation time
oo::objdefine $anotherClassIns export varname

# Then, to access
puts [set [$anotherClassIns varname num]]
# Or
upvar 0 [$anotherClassIns varname num] v
puts $v

有一个类似的方法,但这要求你没有冲突的局部变量:variablenum

# Object creation time
oo::objdefine $anotherClassIns export variable

# Access
$anotherClassIns variable num
puts $num

评论

0赞 Donal Fellows 1/27/2022
请注意,上面后面的示例省略了相当多的样板;这无趣,在所有情况下都完全相同。
0赞 glenn jackman 1/27/2022
如果在创建新实例时要扩展 argv,则 Aclass 构造函数应使用 notAclass new {*}$argvargsargv