在程序中使用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;
参数Text: String
以const
为前缀,以便(据我所知),制作并使用该值的副本 - 并且是只读的。我想知道的是,如果我没有将const
放在那里,这对应用程序有何影响?也许是表演技巧?
答案 0 :(得分:23)
查看documentation州:
“使用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.
答案 1 :(得分:7)
如果您没有const前缀,编译器必须假设您将更改参数。这意味着复制它并设置一个隐藏的尝试...最后处理本地字符串变量,所以有时const可以产生显着的性能提升。它还使生成的代码更小。
答案 2 :(得分:1)
除了以前使用const时的效率答案(即编译器不需要复制变量),如果使用带有Interface参数的const,它会阻止引发ref计数。
答案 3 :(得分:0)
当在函数中使用Activity
参数时,向Delphi编译器保证不会从该函数调用任何其他函数,至少在将所有这些const string
参数复制到其中之前您将拥有的局部变量。
https://plus.google.com/+AriochThe/posts/WB3toSpAdfA
const string
由于volatile字符串和const字符串实际上是两种不同的类型-经典编译器将它们区别对待-应该添加数据转换:当调用const-string函数传递时,其易失性字符串参数Delphi可以增加使用计数器并在函数退出后减小它。将const-strings参数向下传递到下一个const-string函数将是现在的样子,一旦编译器将volatile字符串类型转换为const字符串,它将保持不变。
遗憾的是,事实并非如此。还有龙。
因此,如果您的函数具有const字符串参数-请不要从中调用它,也不要将这些参数缓存到本地vars中。