1. 程式人生 > >Ada語言寶書課程#3:Ada 2005 受限型別— 建構函式

Ada語言寶書課程#3:Ada 2005 受限型別— 建構函式

寶書課程 #3: Ada 2005 受限型別建構函式

by Bob Duff—AdaCore

Translator:Dongfeng.Gu

讓我們開始

考慮到Ada2005允許受限型別的現場集合(宣告),下一步顯然是要將這樣的集合包裝到抽象中--有名的,從函式返回它們。畢竟,有趣的型別通常是私有的,我們也需要一些方法讓客戶端建立和初始化物件。

   package P is

      type T (<>) is limited private

;

      function Make_T (Name : String) return T; – constructor function

   private

      type T is limited

         record

            Name : Unbounded_String;

            My_Task : Some_Task_Type;

            My_Prot : Some_Protected_Type;

         end record;

   end

 P;

   package body P is

      function Make_T (Name : String) return T is

      begin

         return (Name => To_Unbounded_String (Name), others => <>);

      end Make_T;

   end P;

Ada95中,受限型別不能允許有建構函式(就是函式建立新物件並返回它們)。Ada2005則允許完全通用的建構函式。鑑於上述,客戶端可以這樣說:

    My_T : T := Make_T (Name => "Bartholomew Cubbins");

對於集合,Make_T的結果是現場生成的(就是在My_T物件中),而不是先建立而後複製到My_T中增加另一層次的函式呼叫,我們可以這樣做:

   function Make_Rumplestiltskin return T is

   begin

       return Make_T (Name => “Rumplestiltskin”);

   end Make_Rumplestiltskin;

   Rumplestiltskin_Is_My_Name : constant T := Make_Rumplestiltskin;

這可能有助於理解實現模型:在這種情況下,Ruplestaltskin _ Is _ My _ Name是以通常的方式分配的(在棧上,假設它被宣告子程式的本地)。它的地址作為一個額外的隱式引數傳遞給Make_Rumplestaltskin,然後將相同的地址傳遞給Make_T,接著在那個地址現場建立集合。受限物件絕對不能被拷貝!在這種情況下,Make_T將初始化成員Name,並建立My_Task和My_Prot成員,所有這些成員都直接(被建立)在Ruplestaltskin_Is_My_Name中。

注意Rumplestiltskin_Is_My_Name是個常量。在Ada95中,無法建立一個常量的受限物件,因為沒有初始化(受限物件)的方法。

類似於在Ada95中,型別T中的“(<>)”意思是從客戶端角度看它有“未知的判別式”。這是一個防止客戶端建立預設初始化物件的技巧(就是,“X:t;”是非法的)。因此,客戶端每當建立T型別物件的時候必須呼叫Make_T,給與包P對於初始化物件的完全控制。

理想情況下,受限型別和非受限型別應該是相同的,除了本質區別:你不能複製受限物件。Ada2005中允許受限型別的函式與集合使我們非常接近這個目標。一些語言有一個特殊的特徵叫做建構函式。在Ada中,建構函式就是一個建立新物件的函式。除了在Ada95中,這僅用於非受限型別。對於受限型別,唯一的實現建構函式的方法是通過預設值的宣告,這將把你限制在一個建構函式中。將引數傳遞給該建構函式的唯一方法是通過判別。在Ada2005,我們可以說:

 

   This_Set : Set := Empty_Set;

   That_Set : Set := Singleton_Set (Element => 42);

Set是否受限,語句“This_Set : Set := Empty_Set;” 對於我來說看起來比如下語句更清楚:

   This_Set : Set;

(該語句)這可能意味著“預設初始化為空Set”或者可能意味著“暫時先不初始化,我們之後再初始化它”。