Delphi中记录方法和const参数

发布于 2024-12-04 15:16:11 字数 882 浏览 1 评论 0原文

看起来 Delphi 编译器在以下情况下不支持 const 记录参数: 涉及“记录与方法”。

以前没有尝试过滥用 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;

虽然如果您尝试执行 t.Field:='doh';DoStuff fi 中,编译器会正确地抱怨,但你可以调用修改“const”记录的方法,甚至不需要提示或警告。因此,这与引用类型(例如类或动态数组)的行为不同,引用类型允许直接字段写入(因为 const 仅限制对参数本身的更改)。

附录:这也允许以这种方式修改声明的编译时常量,例如:

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

这是接受/记录的行为吗?或者只是编译器的缺点?

It looks like the Delphi compiler does not honor const record parameters when
"records-with-methods" are involved.

Having not tried to abuse the const convention previously, I was a little surprised
to find the compiler accepted code like that:

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'; in DoStuff f.i., the compiler will properly complain, but you're allowed to call methods that modify the "const" record without even a hint or warning. 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).

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

玻璃人 2024-12-11 15:16:11

const 从不对 Delphi 中的方法调用施加任何限制,无论是记录还是类实例。所以我不认为方法调用的处理有什么不一致的地方。

如果无法在作为 const 参数传递的记录上调用方法,那么几乎会导致带有无用方法的记录。例如,这意味着无法调用属性获取器。为了对作为 const 传递的记录施加限制,需要有一个与 C++ 的 const 成员函数等效的概念。这将使编译器知道某些方法是不可改变的。

const never places any restrictions on method calls in Delphi, be they on records or instances of classes. 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. It would mean, for example, that a property getter could not be called. 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++. That would allow the compiler to know that certain methods were non-mutating.

忆依然 2024-12-11 15:16:11

大卫对这个限制分析得很好。如果编译器要检查这些细节,它确实可能会受到一些惩罚。此外,我没有发现编译器的行为有任何问题。获取记录的方法不能直接更改其数据,只能在使用其包含的方法时才可以。在这种情况下,记录的工作方式就像一个对象:您可以以与 const 相同的方式将对象用作 const,但仍然存在您所描述的相同问题,即。对象的方法可用于更改其数据。

对象的好处是,可以将此类方法声明为私有,这使您能够保护其数据。您甚至可以创建一个继承的类来执行此操作,即隐藏更改其数据的所有可能性。也许您想尝试这种方法?

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. 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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文