当我在一个过程的参数中使用"const"时它会有什么不同?

Jer*_*dge 17 delphi parameters constants

const在程序中使用参数时会有什么不同?

以下面的过程为例:

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;
Run Code Online (Sandbox Code Playgroud)

该参数Text: String带有前缀,const以便(据我所知),制作和使用该值的副本 - 并且是只读的.我想知道的是,这对应用程序有何影响,与我没有放在const那里有什么不同?也许是表演技巧?

Ste*_*nke 24

查看文档说明:

"使用const允许编译器优化结构化和字符串类型参数的代码.它还提供了防止无意中通过引用另一个例程传递参数的安全措施."

例如,在字符串的情况下,优化意味着在作为const传递时没有额外的引用计数.也作为const传递并不意味着它是一个副本.它通常在内部作为引用传递,因为编译器确保没有对它的写访问权.

一些非常有趣的文章,以完整地了解幕后发生的事情:

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

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

编辑:

一个简单的例子来说明const可能会导致内部传递:

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.
Run Code Online (Sandbox Code Playgroud)

  • FWIW:对于如何**传递**,参数是否为const无关紧要.如果没有显式声明`var`或`out`,那么对于const或非const,它将被**传递**.通常,大于寄存器大小(例如,32位)的项目将通过引用**传递**,无论它们是否为常量.const和非const之间的唯一区别是,对于非const,隐藏代码在开始时插入,将项目复制到本地存储.对于const,只允许读取引用,因此缺少此复制代码并直接使用传递的引用. (3认同)

500*_*ror 7

如果没有const前缀,编译器必须假定您将更改参数.这意味着复制它并设置一个隐藏的尝试...最后处理本地字符串变量,所以有时const可以产生显着的性能提升.它还使生成的代码更小.