简体   繁体   English

在Delphi中记录方法和const参数

[英]Record methods and const parameters in Delphi

It looks like the Delphi compiler does not honor const record parameters when "records-with-methods" are involved. 当涉及“涉及方法的记录”时,看起来Delphi编译器不支持const记录参数。

Having not tried to abuse the const convention previously, I was a little surprised to find the compiler accepted code like that: 以前没试过滥用const约定,我有点惊讶地发现编译器接受了这样的代码:

type
    TTest = record
       Field : String;
       procedure Update;
    end;

procedure TTest.Update;
begin
    Field := Field + '+1';
end;

procedure DoStuff(const t : TTest);
begin
    ShowMessage(t.Field);
    t.Update;
    ShowMessage(t.Field);
end;

While if you try to do a t.Field:='doh'; 如果你试图做一个t.Field:='doh'; in DoStuff fi, the compiler will properly complain, but you're allowed to call methods that modify the "const" record without even a hint or warning. DoStuff fi中,编译器会正确地抱怨,但是你可以调用修改“const”记录的方法,甚至没有提示或警告。 So this is different behavior than for reference types (such as classes or dynamic arrays), where direct field writes are allowed (as const only restricts changes to the parameter itself). 因此,这与引用类型(例如类或动态数组)不同,其中允许直接字段写入(因为const仅限制对参数本身的更改)。

Addendum : this allows to modify declared compile-time constants this way too, as in: 附录 :这允许以这种方式修改声明的编译时常量,如:

const
   cTest : TTest = (Field : '1');
...
cTest.Update;              // will show '1' then '1'+'1'
ShowMessage(cTest.Field);  // will show '1' (because optimized at compile-time)

Is that an accepted/documented behavior? 这是接受/记录的行为吗? or just a compiler shortcoming? 还是仅仅是编译器的缺点?

const never places any restrictions on method calls in Delphi, be they on records or instances of classes. const永远不会对Delphi中的方法调用施加任何限制,无论是记录还是类的实例。 So I don't think there is anything inconsistent with the treatment of method calls. 所以我不认为与方法调用的处理有任何不一致。

If methods could not be called on record passed as a const parameter, then that would pretty much render records with methods useless. 如果无法在作为const参数传递的记录上调用方法,那么这将使用方法无用的渲染记录。 It would mean, for example, that a property getter could not be called. 例如,这意味着无法调用属性getter。 In order to place restrictions on such records passed as const , there would need to be an equivalent concept to the const member functions of C++. 为了对作为const传递的这些记录施加限制,需要有一个与C ++的const成员函数相同的概念。 That would allow the compiler to know that certain methods were non-mutating. 这将允许编译器知道某些方法是非变异的。

David analyzed the restriction pretty well. 大卫很好地分析了限制。 If the compiler was to check out such details it could really do it with some penalty. 如果编译器要检查这些细节,那么它可能真的会受到一些惩罚。 Additionally I don't see anything wrong with the compiler's behaviour. 另外,我没有看到编译器的行为有任何问题。 The method which gets the record can't directly alter its data, but only when using the method it contains. 获取记录的方法不能直接改变其数据,而只能在使用它包含的方法时。 The record in this case works like an object: you can in the same way an object as a const and still have the same problem you described, ie. 这种情况下的记录就像一个对象:你可以用一个对象作为const,并且仍然有你描述的相同问题,即。 the object's methods can be used to alter its data. 对象的方法可用于改变其数据。

The benefit of the object is, that such methods can be declared to be private, which enables you to protect its data. 该对象的好处是,可以将此类方法声明为私有,这使您可以保护其数据。 You could even create an inherited class which does just that, namely hiding all possibility to alter its data. 您甚至可以创建一个继承的类,即可以隐藏改变其数据的所有可能性。 Maybe you want to try this approach? 也许你想尝试这种方法?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM