2012-06-12 13 views
15

Bir yordamda const parametresini kullandığımda ne fark eder?Bir yordamın parametresinde "const" kullandığımda ne fark eder?

örneğin aşağıdaki yordamı uygulayın:

procedure DoSomething(Sender: TObject; const Text: String; var Reply: String); 
begin 
    //Text is read-only and Reply will be passed back wherever DoSomething() was called 
    Reply:= Text; 
end; 

Text: String, değerin bir kopyası yapılmış ve kullanılan (bildiğim kadarıyla) bu yüzden const o öneki parametreyi - ve salt okunur . Merak ettiğim şey, bu uygulamayı, const'u oraya koymadığımdan farklı bir şekilde nasıl etkiliyor? Belki bir performans numarası? Eğer const öneki yok

+1

Burada mı yanıtladı? Çoğu durumda http://stackoverflow.com/a/1601124/496736 –

+2

, dikkatle const' 'olarak tüm giriş-tek parametreleri işaretleme önemli yararı, programcı, ek bir yardım saçma kaçınarak alacak olduğunu düşünüyorum böcek. –

+1

@Andreas Galling, 'const' ın hem arayüze hem de uygulamaya dahil edilmesi gerektiğidir. Bu, C++ 'nın Delphi'yi dövdüğü bir alandır. –

cevap

22

documentation devletler baktığımızda:

". Derleyici yapılandırılmış kodunu optimize etmek için const sağlar kullanma - ve dize tipi parametreleri Ayrıca istemeden başka rutin referans ile bir parametre geçirerek karşı bir koruma sağlar"

örneğin bir dize halinde optimizasyon const olarak geçerken hiçbir ek refcounting olmadığı anlamına gelir. Ayrıca const olarak geçmek değil, bir kopya anlamına gelir. Genellikle derleyici referans olarak geçer çünkü derleyici buna yazma izni vermez.

Bazı çok ilginç makaleler tamamen başlık altında neler olduğunu anlamak için:

http://delphitools.info/2010/07/28/all-hail-the-const-parameters

http://vcldeveloper.com/articles/different-function-parameter-modifiers-in-delphi

Düzenleme:

tarafından geçişte neden olabileceğini const göstermek için basit bir örnek içten referansı:

program Project1; 

{$APPTYPE CONSOLE} 

type 
    PMyRecord = ^TMyRecord; 
    TMyRecord = record 
    Value1: Cardinal; 
    Value2: Cardinal; 
    end; 

procedure PassAsConst(const r: TMyRecord); 
begin 
    PMyRecord(@r).Value1 := 3333; 
    PMyRecord(@r).Value2 := 4444; 
end; 

procedure PassByVal(r: TMyRecord); 
begin 
    PMyRecord(@r).Value1 := 3333; 
    PMyRecord(@r).Value2 := 4444; 
end; 

var 
    r: TMyRecord; 
begin 
    r.Value1 := 1111; 
    r.Value2 := 2222; 
    PassByVal(r); 
    Writeln(r.Value1); 
    Writeln(r.Value2); 

    PassAsConst(r); 
    Writeln(r.Value1); 
    Writeln(r.Value2); 

    Readln; 
end. 
+3

FWIW: nasıl ** geçirilir **, bir parametrenin yapılıp yapılmadığı önemli değil. Açıkça "var" veya "out" olarak bildirilmemişse, const veya non-const için ** aynı şekilde ** geçirilecektir. Genel olarak, kayıt boyutu (örneğin, 32 bit) daha büyük olan öğeler, const olup olmadıklarına bakılmaksızın, referansla ** ** geçirilir. Const ile const olmayanlar arasındaki tek fark, const olmayan için, öğenin yerel depoya kopyalandığı başlangıçta gizli kodun eklenmesidir. Const için, sadece okuma referanslarına izin verilir, bu nedenle bu kopyalama kodu eksik ve geçirilen referans doğrudan kullanılır. –

6

, derleyici parametreyi değiştirerek olacağını varsaymak zorundadır. Bu, kopyalama ve yerel bir dize değişkeni atmak için nihayet gizli bir denemeyi kurmak anlamına gelir, bu yüzden bazen const önemli bir performans iyileştirmesi sağlayabilir. Ayrıca oluşturulan kodu daha küçük hale getirir.

+0

Bunun en son kurduğum Delphi 2007'den itibaren bunun doğru olduğunu eklemeliyim. Daha gelişmiş bir derleyici, bir parametrenin gerçekte const öneki olmadan bile bir değişken olarak kullanılmadığını ve kopyalanmamasını potansiyel olarak algılayabildiğini, ancak bu optimizasyon türlerinin tarihsel olarak Delphi AR-GE ekibinin odağı olmadığını fark edebilirim. –

+0

Tüm Delphi sürümlerinde const parametrelerini, yani D2007'den önce iyi bilir: Yapıları kopyalamaya gerek yoktur, eğer referans olarak (bu boyutlarına bağlı olarak değişir), yerel depolamaya ve referans sayımına gerek yoktur. –

1

Bir const kullanıldığında verimin önceki yanıtlarına ek olarak (ör. Arabirim parametresi olan bir const kullanırsanız, ref sayımının tetiklenmesini engeller.

+0

Bu davranışa neden budur: http://qc.embarcadero.com/wc/qcmain.aspx?d=75036 –

+3

Referans sayımının olmaması, arabirimler ve dizeler için aynıdır. Arayüzler hakkında söyledikleriniz, dizelerle ilgili şeylere "ek olarak" değildir. * Değişkeni * her zaman kopyalanır, ancak bu kopyaları kopyalamak sadece bir işaretçinin değerini kopyalamaktan ötürü ucuzdur, ki bu bazen bir değer formunu diğerine kopyalamaktan başka bir şey değildir. –

İlgili konular