棧(stack)是存放函數的所有動態局部變量及函數調用和返回的有關信息的一塊內存。棧的內存管理嚴格遵循先進後出的順序,這一點正是實現函數調用所需要的。從棧中分配內存效率特別高。數據對象使用棧中的內存(如動態局部變量)比使用堆中內存會使程序運行更快。
堆(heap)是供malloc()、calloc()、realloc()和new等函數獲取內存空間的一塊內存。從堆中獲取內存比從棧中要慢得多,但堆的內存管理卻比棧靈活得多,任何時候你都可以從堆中獲取(或釋放)內存,我們可以按任意順序進行。用來存放遞歸數據結構的內存幾乎都要從堆中獲取。用來存放字符串的內存通常也從堆中獲取,尤其是對那些在程序運行時可能出現的很長的字符串。
從堆中獲取的內存要用free()、delete來釋放,它本身不會自動釋放。
C編譯的程序能產生如此優質的代碼、程序運行的快速與對棧的正確運用是有關的,但Object Pascal中所有的對象都只能建構於堆中,無法和C++一樣,能夠在棧(在函數內創建類的對象)、數據區段(在函數外創建類的對象)、堆(用new等函數來創建類的對象)三種地方建立對象,所以VCL類的對象我們只能在堆中創建。
如創建一個按鈕對象,我們可以這樣來創建:
TButton *btnMy= new Tbutton(From1);
可以寫成如下程式:類名 *對象名=new 類名(…);
注意:()裡面可以是你已創建的該類對象的父類名字、工程的名字、NULL或this。但最好是對象的父類名。
例:動態生成按鈕
我們先在窗體(Form1)上,放一個按鈕Button1,在他的單擊事件中寫上如下代碼:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TButton *my=new TButton(Form1);
my->Parent=Form1;//最為關鍵的一句,否則你將看不到什麼,但編譯卻是正確的
my->Top=200;
my->Left=200;
my->Height=25;
my->Width=75;
my->Caption="I'm Button!";
//my->Visible=true;此語句可有可無,因為他的父類通常默認他可見
}
通過這個例子我們應該清楚的看出動態創建組件的幾個重要步驟:
1)要一個空間(內存);// TButton *my=new TButton(Form1);
2)指定其父組件,說直接了就是我們要創建的這個對象要放在那個容器上;// my->Parent=Form1;
3)指定組件要出現在父類的那個位置;//my->Top=200;my->Left=200;my->Height=25; my->Width=75;所以這個屬性你一定要設置好位置;
4)其它重要屬性。// my->Caption="I'm Button!";
並且其順序不能反了,否則你的程序會出笑話的。
在動態生成非寶蘭VCL原有的組件時要加上對應的頭文件。如,我們要動態生成報表組件一定要加入:
#include “Qrctrls.hpp”//若還有問題,你還要加入:
#include “QuickRpt.hpp”
另外由於BCB對內存管理或與系統、硬件的沖突,你的動態創建程序也許一點錯誤都沒有,但就是編譯不了;有時也許第一次通過了,第二次一樣的程序卻通過不了,出現這樣那樣的提示,最簡單的辦法就是注銷一下系統,再試一下,多數就能解決了。