術(shù)語匯編 Perl析構(gòu)函數(shù)簡介
本文和大家重點(diǎn)討論一下Perl析構(gòu)函數(shù),Perl跟蹤對象的鏈接數(shù)目,當(dāng)某對象的***一個(gè)應(yīng)用釋放到內(nèi)存池時(shí),該對象就自動(dòng)銷毀。對象的析構(gòu)發(fā)生在代碼停止后,腳本將要結(jié)束時(shí)。
Perl析構(gòu)函數(shù)
一、Perl析構(gòu)函數(shù)簡介
Perl跟蹤對象的鏈接數(shù)目,當(dāng)某對象的***一個(gè)應(yīng)用釋放到內(nèi)存池時(shí),該對象就自動(dòng)銷毀。對象的析構(gòu)發(fā)生在代碼停止后,腳本將要結(jié)束時(shí)。對于全局變量而言,析構(gòu)發(fā)生在***一行代碼運(yùn)行之后。
如果你想在對象被釋放之前獲取控制權(quán),可以定義DESTROY()方法。DESTROY()在對象將釋放前被調(diào)用,使你可以做一些清理工作。DESTROY()函數(shù)不自動(dòng)調(diào)用其它DESTROY()函數(shù),Perl不做內(nèi)置的析構(gòu)工作。如果構(gòu)造函數(shù)從基類多次bless,DESTROY()可能需要調(diào)用其它類的DESTROY()函數(shù)。當(dāng)一個(gè)對象被釋放時(shí),其內(nèi)含的所有對象引用自動(dòng)釋放、銷毀。
一般來說,不需要定義DESTROY()函數(shù),如果需要,其形式如下:
- subDESTROY{
- #
- #Addcodehere.
- #
- }
因?yàn)槎喾N目的,Perl使用了簡單的、基于引用的垃圾回收系統(tǒng)。任何對象的引用數(shù)目必須大于零,否則該對象的內(nèi)存就被釋放。當(dāng)程序退出時(shí),Perl的一個(gè)徹底的查找并銷毀函數(shù)進(jìn)行垃圾回收,進(jìn)程中的一切被簡單地刪除。在UNIX類的系統(tǒng)中,這像是多余的,但在內(nèi)嵌式系統(tǒng)或多線程環(huán)境中這確實(shí)很必要。
二、Perl析構(gòu)函數(shù)之繼承
類方法通過@ISA數(shù)組繼承,變量的繼承必須明確設(shè)定。下例創(chuàng)建兩個(gè)類Bean.pm和Coffee.pm,其中Coffee.pm繼承Bean.pm的一些功能。此例演示如何從基類(或稱超類)繼承實(shí)例變量,其方法為調(diào)用基類的構(gòu)造函數(shù)并把自己的實(shí)例變量加到新對象中。
Bean.pm代碼如下:
- packageBean;
- requireExporter;
- @ISA=qw(Exporter);
- @EXPORT=qw(setBeanType);
- subnew{
- my$type=shift;
- my$this={};
- $this->{'Bean'}='Colombian';
- bless$this,$type;
- return$this;
- }
- #
- #Thissubroutinesetstheclassname
- subsetBeanType{
- my($class,$name)=@_;
- $class->{'Bean'}=$name;
- print"Setbeanto$name\n";
- }
- 1;
此類中,用$this變量設(shè)置一個(gè)匿名哈希表,將'Bean'類型設(shè)為'Colombian'。方法setBeanType()用于改變'Bean'類型,它使用$class引用獲得對對象哈希表的訪問。
三、Perl析構(gòu)函數(shù)之子類方法的重載
繼承的好處在于可以獲得基類輸出的方法的功能,而有時(shí)需要對基類的方法重載以獲得更具體或不同的功能。下面在Bean.pm類中加入方法printType(),代碼如下:
- subprintType{
- my$class=shift@_;
- print"ThetypeofBeanis$class->{'Bean'}\n";
- }
然后更新其@EXPORT數(shù)組來輸出:
@EXPORT=qw(setBeanType,printType);
現(xiàn)在來調(diào)用函數(shù)printType(),有三種調(diào)用方法:
- $cup->Coffee::printType();
- $cup->printType();
- $cup->Bean::printType();
輸出分別如下:
ThetypeofBeanisMixed
ThetypeofBeanisMixed
ThetypeofBeanisMixed
為什么都一樣呢?因?yàn)樵谧宇愔袥]有定義函數(shù)printType(),所以實(shí)際均調(diào)用了基類中的方法。如果想使子類有其自己的printType()函數(shù),必須在Coffee.pm類中加以定義:
- #
- #Thisroutineprintsthetypeof$class->{'Coffee'}
- #
- subprintType{
- my$class=shift@_;
- print"ThetypeofCoffeeis$class->{'Coffee'}\n";
- }
然后更新其@EXPORT數(shù)組:
@EXPORT=qw(setImports,declareMain,closeMain,printType);
現(xiàn)在輸出結(jié)果變成了:
ThetypeofCoffeeisInstant
ThetypeofCoffeeisInstant
ThetypeofBeanisMixed
現(xiàn)在只有當(dāng)給定了Bean::時(shí)才調(diào)用基類的方法,否則直接調(diào)用子類的方法。
那么如果不知道基類名該如何調(diào)用基類方法呢?方法是使用偽類保留字SUPER::。在類方法內(nèi)使用語法如:$this->SUPER::function(...argumentlist...);,它將從@ISA列表中尋找。剛才的語句用SUPER::替換Bean::可以寫為$cup->SUPER::printType();,其結(jié)果輸出相同,為:
ThetypeofBeanisMixed
四、Perl析構(gòu)函數(shù)中Perl類和對象的一些注釋
OOP的***好處就是代碼重用。OOP用數(shù)據(jù)封裝來隱藏一些復(fù)雜的代碼,Perl的包和模塊通過my函數(shù)提供數(shù)據(jù)封裝功能,但是Perl并不保證子類一定不會直接訪問基類的變量,這確實(shí)減少了數(shù)據(jù)封裝的好處,雖然這種動(dòng)作是可以做到的,但卻是個(gè)很壞的編程風(fēng)格。
注意:
1、一定要通過方法來訪問類變量。
2、一定不要從模塊外部直接訪問類變量。
當(dāng)編寫包時(shí),應(yīng)該保證方法所需的條件已具備或通過參數(shù)傳遞給它。在包內(nèi)部,應(yīng)保證對全局變量的訪問只用通過方法傳遞的引用來訪問。對于方法要使用的靜態(tài)或全局?jǐn)?shù)據(jù),應(yīng)該在基類中用local()來定義,子類通過調(diào)用基類來獲取。有時(shí),子類可能需要改變這種數(shù)據(jù),這時(shí),基類可能就不知道怎樣去尋找新的數(shù)據(jù),因此,這時(shí)***定義對該數(shù)據(jù)的引用,子類和基類都通過引用來改變該數(shù)據(jù)。
***,你將看到如下方式來使用對象和類:
usecoffee::Bean;
這句語句的含義是“在@INC數(shù)組所有目錄的Coffee子目錄來尋找Bean.pm”。如果把Bean.pm移到./Coffee目錄,上面的例子將用這一use語句來工作。這樣的好處是有條理地組織類的代碼。再如,下面的語句:
useAnother::Sub::Menu;
意味著如下子目錄樹:./Another/Sub/Menu.pm
【編輯推薦】