本章主要介紹<b>Open</b> <b>CASCADE</b>的基本功能,如記憶體管理(<b>memory</b> <b>management</b>)、搖桿程式設計(<b>programming</b> <b>with</b> <b>handles</b>)、基本類型(<b>primitive</b> <b>types</b>)、異常處理(<b>exception</b> <b>handling</b>)、泛型程式設計(<b>genericity</b> <b>by</b> <b>downcasting</b>)、<b>Plug</b>-<b>in</b>的建立等……
一、資料類型 <b>Data</b> <b>Types</b>
1.1 基本類型 <b>Primitive</b> <b>Types</b>
基本類型是由語言定義的且他們是由值控制的。有些基本類型從類<b>Storable</b>繼承而來。這就意味着他們可以在持久性對象中使用,或者被包含在對象的方法中,或者作為對象内部的一部分。由類<b>Standard</b>_<b>Storable</b>派生的類有:
l <b>Boolean</b>: 用來表示邏輯資料。隻有兩種狀态:<b>Standard</b>_<b>True</b>和<b>Standard</b>_<b>False</b>;
l <b>Character</b>: 用來表示任意<b>ASCII</b>字元;
l <b>ExtCharacter</b>: 用來表示字元的擴充;
l <b>Integer</b>: 用來表示整數;
l <b>Real</b>: 用來表示實數;
l <b>ShortReal</b>: 用來表示實數的另一種選擇,精度要低;
也有非存儲類型,如:
l <b>CString</b>:
l <b>ExtString</b>:
l <b>Address</b>:
下表所示為<b>Open</b> <b>CASCADE</b>中基本類型與<b>C</b>++中基本類型對應表:
<b>C</b>++ <b>Types</b>
<b>Open</b> <b>CASCADE</b> <b>Types</b>
<b>int</b>
<b>Standard</b>_<b>Integer</b>
<b>double</b>
<b>Standard</b>_<b>Real</b>
<b>float</b>
<b>Standard</b>_<b>ShortReal</b>
<b>unsigned</b> <b>int</b>
<b>Standard</b>_<b>Boolean</b>
<b>Standard</b>_<b>False</b> = 0;
<b>Standard</b>_<b>True</b> = 1;
<b>char</b>
<b>Standard</b>_<b>Character</b>
<b>short</b>
<b>Standard</b>_<b>ExtCharacter</b>
<b>char</b>*
<b>Standard</b>_<b>CString</b>
<b>void</b>*
<b>Standard</b>_<b>Address</b>
<b>short</b>*
<b>Standard</b>_<b>ExtString</b>

具體請參考《<b>Open</b> <b>CASCADE</b> <b>Foundation</b> <b>Classes</b> <b>User</b>'<b>s</b> <b>Guide</b>》;
1.2 由值控制的類型
由值控制的變量類型分為三類:
l 基本類型;
l 枚舉類型;
l 不是由類<b>Standard</b>_<b>Persistent</b>直接或間接派生的類;
由值控制的變量比由搖桿控制的變量更直接,更快,就是不能儲存到檔案。
1.3 由引用控制的類型
由搖桿控制的變量分為兩類:
l 由類<b>Persistent</b>派生的類,這種類可以儲存到檔案;
l 由類<b>Transient</b>派生的類;
1.4 屬性的結論
二、搖桿程式設計 <b>Programming</b> <b>with</b> <b>Handles</b>
2.1 搖桿定義 <b>Handle</b> <b>Definition</b>
搖桿與<b>C</b>++的指針(<b>pointer</b>)類似。幾個搖桿可以引用同一個對象,同樣地,一個搖桿也可以引用了幾個對象,但是一次隻能是一個對象。為了通路引用的對象,必須先解除引用(<b>de</b>-<b>referenced</b>),就像使用<b>C</b>++的指針一樣。臨時變量和持久變量既可以是由值控制的也可以是由搖桿控制的。引用非持久性對象的搖桿稱為不可存儲搖桿。是以,持久性對象不能包含不可存儲搖桿。
類的組織:使用搖桿的類的對象可以是持久的也可是臨時的。從類<b>Standard</b>_<b>Transient</b>繼承的類的執行個體是臨時的,而從類<b>Standard</b>_<b>Persistent</b>繼承的類的執行個體是持久的。本章隻讨論臨時類及其相關的搖桿。持久類及其相關的搖桿的組織與此類似。
類<b>Standard</b>_<b>Transient</b>是<b>Open</b> <b>CASCADE</b>中由搖桿控制的類層次結構中的基類。它有引用計數部分,所有的子類都繼承此部分。當使用<b>Handle</b>()類時,就可知引搖桿引用執行個體的數量。
直接或間接由類<b>Transient</b>派生的類,<b>CDL</b> <b>extractor</b>将建立類的相應的搖桿<b>Handle</b>(),類名是相同的,隻是在類名前加上了“<b>Handle</b>_*”。<b>Open</b> <b>CASCADE</b>提供預處理器的宏定義<b>Handle</b>(),用來産生相應類的帶搖桿的類。
使用搖桿:在對臨時對象執行任何操作之前,你必須聲明搖桿。如:若點(<b>Point</b>)和線(<b>Line</b>)是從包<b>Geom</b>中定義的兩個臨時對象,代碼如下:
聲明搖桿建立了一個未指向任何對象的空搖桿。搖桿可以通過其方法<b>IsNull</b>()來驗證。使用搖桿無效,可使用方法<b>Nullify</b>()。
隻要類型相容,既可以從建立新的對象或通過指派來初始化搖桿。搖桿僅用于共享的對象。對于所有的本地操作,建議使用由值控制的類。
2.2 類型管理 <b>Type</b> <b>Management</b>
<b>Open</b> <b>CASCADE</b>提供一種描述資料類型層次的通用方式,并且可以運作時檢查對象類型,與<b>C</b>++的<b>RTTI</b>類似。對于從類<b>Standard</b>_<b>Transient</b>繼承的每個類,<b>CDL</b> <b>extractor</b>從類<b>Standard</b>_<b>Type</b>建立代碼。由類<b>Standard</b>_<b>Transient</b>派生的類的虛函數<b>DynamicType</b>()傳回一個執行個體。通過虛函數<b>IsKind</b>()來檢查給定的對象是不是指定的類型。
2.3 使用搖桿建立對象 <b>Using</b> <b>Handles</b> <b>to</b> <b>Create</b> <b>Objects</b>
建立由搖桿控制的對象,聲明搖桿并使用标準<b>C</b>++的<b>new</b>操作符,緊随其後調用構造函數。
與指針不同的是,搖桿不需要<b>delete</b>。因為當搖桿引用的對象為零時,對象将會被自動釋放。
2.4 方法調用 <b>Invoking</b> <b>Methods</b>
當你使用搖桿的時候,就跟使用<b>C</b>++的指針一樣。調用搖桿引用對象的方法使用操作符->。檢查或修改搖桿的狀态,通過操作符點.來實作。下例所示為通路一個點對象的坐标:
下例所示為如何檢查笛卡爾坐标點的類型:
當調用一個空<b>Null</b>搖桿時,<b>NullObject</b>異常将會産生。
調用類方法:類方法就是<b>C</b>++類中的靜态函數。即用類名加上“::”和方法名來調用。
2.5 搖桿釋放 <b>Handle</b> <b>De</b>-<b>allocation</b>
在删除一個對象之前,必須其沒有被引用。為了減少管理對象生命周期的程式設計工作量,<b>Open</b> <b>CASCADE</b>中對象的删除函數是由搖桿控制類的引用計數(<b>reference</b> <b>counter</b>)來確定。搖桿就是用來管理引用計數,當對象不再引用時将會調用<b>delete</b>将其删除。當是<b>Standard</b>_<b>Transient</b>的子類時,通常不需要直接使用<b>delete</b>操作符。當對相同的對象使用<b>new</b>時,引用計數将會增加。當搖桿被銷毀、置為空或重新指派,引用計數将會減少。當引用計數為0時對象将會自動調用<b>delete</b>操作符。記憶體配置設定的原理如下所示:
<b>Cycles</b>
本段内容不清楚,具體内容請參考原文。
2.6 不使用<b>CDL</b>建立類 <b>Creating</b> <b>Transient</b> <b>Classes</b> <b>without</b> <b>CDL</b>
盡管可用<b>CDL</b> <b>extractor</b>生成搖桿類及其相關<b>C</b>++代碼,然而也可不用<b>CDL</b>管理搖桿。為此,在檔案<b>Standard</b>_<b>DefineHandle</b>.<b>hxx</b>中提供了幾個宏定義:
<b>DECLARE</b>_<b>STANDARD</b>_<b>HANDLE</b>(<b>class</b>_<b>name</b>, <b>ancestor</b>_<b>name</b>) 這個宏定義了以<b>class</b>_<b>name</b>為類名并繼承類<b>ancestor</b>_<b>name</b>的搖桿類。這個宏必須放在頭檔案中,且基類必須是可用的。
<b>IMPLEMENT</b>_<b>STANDARD</b>_<b>HANDLE</b>(<b>class</b>_<b>name</b>, <b>ancestor</b>_<b>name</b>) 這個宏實作了轉換方法<b>DownCast</b>(),應該在<b>C</b>++檔案中使用。
<b>DEFINE</b>_<b>STANDARD</b>_<b>RTTI</b>(<b>class</b>_<b>name</b>) 這個宏聲明方法需要<b>RTTI</b>支援,應該在類的<b>public</b>中使用。
<b>IMPLEMENT</b>_<b>STANDARD</b>_<b>RTTIEXT</b>(<b>class</b>_<b>name</b>, <b>ancestor</b>_<b>name</b>) 實作上面的方法。
注:在使用這些宏的時候,必須確定參數的正确性,特别是父類的名字。否則定義将會不正确,且編譯也不會報錯。
三、記憶體管理 <b>Memory</b> <b>Management</b> <b>in</b> <b>Open</b> <b>CASCADE</b>
在幾何模組化的過程中,程式建立和删除相當數量的<b>C</b>++對象在動态記憶體中,也就是堆中(<b>heap</b>)。在這種情況下,标準函數管理記憶體的性能可能不足夠。是以,<b>Open</b> <b>CASCADE</b>在标準包中實作了記憶體的管理。
3.1 用法 <b>Usage</b>
使用<b>Open</b> <b>CASCADE</b>記憶體管理隻需要在<b>C</b>中使用<b>malloc</b>()的地方使用<b>Standard</b>::<b>Allocate</b>();在使用<b>free</b>()的地方使用<b>Standard</b>::<b>Free</b>();在使用<b>realloc</b>()的地方使用<b>Standard</b>::<b>Reallocate</b>()。
在<b>C</b>++中,類的操作符<b>new</b>()和<b>delete</b>()已經定義了在申請記憶體時使用<b>Standard</b>::<b>Allocate</b>()并在釋放時使用<b>Standard</b>::<b>Free</b>()。是以,類所有的對象的記憶體都将由<b>Open</b> <b>CASCADE</b>的記憶體管理器來管理。
<b>CDL</b> <b>extractor</b>為所有的類定義了<b>new</b>()和<b>delete</b>()。是以,所有的<b>Open</b> <b>CASCADE</b>的類(小部分除外)都使用<b>Open</b> <b>CASCADE</b>的記憶體管理器。
由于操作符<b>new</b>()和<b>delete</b>()被繼承,是以,所有從<b>Open</b> <b>CASCADE</b>派生的類,所有從<b>Standard</b>_<b>Transient</b>類派生的類都是由記憶體管理器管理。
注:若重載了部分從<b>Standard</b>_<b>Transient</b>類派生類的<b>new</b>()和<b>delete</b>(),盡管不推薦這樣做,方法<b>Delete</b>()必須重定義,以便對這樣的指針使用<b>delete</b>操作。這将確定合适的<b>delete</b>()函數将會被調用,即使是由搖桿控制的對象。
3.2 配置記憶體管理器 <b>Configuring</b> <b>Memory</b> <b>Manager</b>
<b>Open</b> <b>CASCADE</b>記憶體管理器可以被配置以便對不同的記憶體區域使用不同的優化技術,或者根本不使用任何優化而直接使用<b>C</b>的<b>malloc</b>()和<b>free</b>()函數。配置方法為修改環境變量的值:
l <b>MMGT</b>_<b>OPT</b>:
l <b>MMGT</b>_<b>CLEAR</b>:
l <b>MMGT</b>_<b>CELLSIZE</b>:
l <b>MMGT</b>_<b>NBPAGES</b>:
l <b>MMGT</b>_<b>THRESHOLD</b>:
l <b>MMGT</b>_<b>REENTRANT</b>:
3.3 實作細節 <b>Implementation</b> <b>details</b>
本段内容請參考原文。
四、異常處理 <b>Exception</b> <b>Handling</b>
異常處理提供了一種從指定點轉換到其他點的一種方法。一個方法可能會産生一個異常,将程式從正常執行處轉換到捕捉異常處。<b>Open</b> <b>CASCADE</b>提供了異常類的層次,其基類是包<b>Standard</b>中的<b>Standard</b>_<b>Failure</b>。<b>CDL</b> <b>extractor</b>使用标準接口生成異常類。
<b>Open</b> <b>CASCADE</b>也提供将系統信号的轉換成異常的支援,如數除0這樣所有的情況都可以用安全、統一的方法來處理了。但是為了支援不同的平台,也使用了一些特殊的方法。
如下内容為在<b>Open</b> <b>CASCADE</b>中使用異常處理的推薦方法。
4.1 産生異常 <b>Raising</b> <b>an</b> <b>Exception</b>
類<b>C</b>++的文法:産生适當的異常将需要調用指定類型的<b>Raise</b>()方法。
産生了一個<b>DomainError</b>類型的異常并可附上相關資訊“<b>Cannot</b> <b>cope</b> <b>with</b> <b>this</b> <b>condition</b>”,資訊字元串是可選的。這個異常可以被捕捉<b>DomainError</b>類型的<b>Handler</b>捕捉到:
正常使用異常處理:異常不能被當作程式設計技巧來替代“<b>goto</b>”,但可作為防止方法被誤用的一種方法。
五、<b>Plug</b>-<b>In</b>管理
六、結論
本章内容介紹了一些<b>C</b>++程式設計的知識及<b>Open</b> <b>CASCADE</b>對<b>C</b>++的包裝。其中,搖桿程式設計是<b>C</b>++中常見的方法,這種引用計數的方式使記憶體的管理更友善。
<a href="mailto:[email protected]"><b>eryar</b>@163.<b>com</b></a>
<b>Pudongxin</b> <b>Shanghai</b> <b>China</b>
<b>2012-8-23</b>