2011-12-11 138 views
5

只是試圖在ObjectPascal/Delphi中實現C/C++靜態局部變量的類似功能。 讓我們在C下面的函數:真C靜態局部變量替換?

bool update_position(int x, int y) 
{ 
    static int dx = pow(-1.0, rand() % 2); 
    static int dy = pow(-1.0, rand() % 2); 

    if (x+dx < 0 || x+dx > 640) 
     dx = -dx; 
    ... 
    move_object(x+dx, y+dy); 
    ... 
} 

使用類型的常量爲一個靜態變量替換無法對其進行編譯的等效ObjectPascal代碼:

function UpdatePosition(x,y: Integer): Boolean; 
const 
    dx: Integer = Trunc(Power(-1, Random(2))); // error E2026 
    dy: Integer = Trunc(Power(-1, Random(2))); 
begin 
    if (x+dx < 0) or (x+dx > 640) then 
    dx := -dx; 
    ... 
    MoveObject(x+dx, y+dy); 
    ... 
end; 

[DCC錯誤] test_f.pas(332): E2026期望的恆定表達式

那麼有沒有辦法一次性通過初始化本地變量?

+0

一個更明智的選擇可能是給你的功能了自己的單位,並宣佈全球在該單元的實現VAR部分。它對那個單位是私人的,因此對那個職能是私人的。我甚至想到我想要這樣做的時候很難,而不是使用具有私人領域的對象。 –

回答

6

Delphi中沒有C靜態變量的直接等價物。

可寫類型的常量(請參閱user1092187's answer)幾乎等效。它具有相同的範圍和實例屬性,但不允許使用C或C++靜態變量進行一次初始化。無論如何,我認爲可以將可寫類型常量作爲一個古怪的歷史腳註來回避。

您可以使用全局變量。

var 
    dx: Integer; 
    dy: Integer 

function UpdatePosition(x,y: Integer): Boolean; 
begin 
    if (x+dx < 0) or (x+dx > 640) then 
    dx := -dx; 
    ... 
    MoveObject(x+dx, y+dy); 
    ... 
end; 

你要做的一次性初始化在initialization部分:

initialization 
    dx := Trunc(Power(-1, Random(2))); 
    dy := Trunc(Power(-1, Random(2))); 

當然,這不同於做一個C靜態變量的範圍有限的全局命名空間的混亂。在現代Delphi中,你可以把它全部包裝到一個類中,並且使用類方法,類變量,class constructors的組合來避免污染全局名稱空間。

type 
    TPosition = class 
    private class var 
    dx: Integer; 
    dy: Integer; 
    private 
    class constructor Create; 
    public 
    class function UpdatePosition(x,y: Integer): Boolean; static; 
    end; 

class constructor TPosition.Create; 
begin 
    dx := Trunc(Power(-1, Random(2))); 
    dy := Trunc(Power(-1, Random(2))); 
end; 

class function TPosition.UpdatePosition(x,y: Integer): Boolean; 
begin 
    // your code 
end; 
+0

Thx爲答案,大衛。畢竟,我強調要使用局部變量來避免全局空間。應用程序應該是線程安全的。可能要使用類包裝解決方法。 –

+0

因爲我相信你知道C靜態代碼不是線程安全的。並且類包裝方法也不會是線程安全的。您需要某種形式的鎖定或無鎖編碼。 –

+0

'類構造函數TPosition.Create'和'經典''構造函數TPosition.Create'之間有什麼區別? –

4

啓用"Writable typed constants"

{$J+} 
procedure abc; 
const 
    II: Integer = 45; 

begin 
    Inc(II); 
    ShowMessage(IntToStr(II)); 
end; 
{$J-} 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    abc; 
    abc; 
    abc; 
end; 
+0

這確實可行,但不是在執行項目範圍的編譯器選項,所以始終首選['{$ WRITEABLECONST}'](http://docwiki.embarcadero.com/RADStudio/en/Writeable_typed_constants_(Delphi))「指令。所有這一切,我對這個選項有點懷疑,因爲它使所有常量在活動時是靜態和可寫的。 –

+0

可寫類型常量無法完成的是在問題代碼中執行的初始化類型。 –