首页 文章

在Delphi中记录方法和const参数

提问于
浏览
11

当涉及"records-with-methods"时,看起来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;

如果你试图在DoStuff f.i中做 t.Field:='doh'; ,编译器会正确地抱怨,但你可以调用修改"const"记录的方法,甚至没有提示或警告 . 因此,这与引用类型(例如类或动态数组)不同,其中允许直接字段写入(因为const仅限制对参数本身的更改) .

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

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

这是接受/记录的行为吗?还是仅仅是编译器的缺点?

2 回答

  • 4

    大卫很好地分析了限制 . 如果编译器要检查这些细节,它可能真的会有一些惩罚 . 另外,我没有看到编译器的行为有任何问题 . 获取记录的方法不能直接改变其数据,而只能在使用它包含的方法时 . 这种情况下的记录就像一个对象:你可以用一个对象作为const,但仍然有你描述的相同问题,即 . 对象的方法可用于改变其数据 .

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

  • 14

    const 永远不会对Delphi中的方法调用施加任何限制,无论是记录还是类实例 . 所以我认为与方法调用的处理方法没有任何不一致之处 .

    如果无法在作为 const 参数传递的记录上调用方法,那么这将使用方法无用的渲染记录 . 例如,这意味着无法调用属性getter . 为了对传递为 const 的记录设置限制,需要有一个与C的const成员函数相同的概念 . 这将允许编译器知道某些方法是非变异的 .

相关问题