【发布时间】:2011-03-10 14:46:53
【问题描述】:
请有人解释一下 Delphi 中公共和已发布的班级成员有什么区别?
我尝试查看 Delphi 帮助,我了解这些成员具有相同的可见性,但我不太了解它们有何不同以及何时应该使用已发布成员而不是公共成员。
非常感谢。
【问题讨论】:
请有人解释一下 Delphi 中公共和已发布的班级成员有什么区别?
我尝试查看 Delphi 帮助,我了解这些成员具有相同的可见性,但我不太了解它们有何不同以及何时应该使用已发布成员而不是公共成员。
非常感谢。
【问题讨论】:
编译器为已发布成员生成 RTTI(运行时类型信息)元数据,但不为公共成员生成(默认情况下)。这样做的主要效果是对象的已发布属性将在设计时出现在 Object Inspector 中。
我不知道您是否正在编写组件,但如果您这样做,您可能知道属性和事件通常是发布的,因此可以使用 Object Inspector 进行设置。
public
property MyProperty: integer read FMyProperty write FMyProperty
MyProperty 将在对象检查器中不可见。
published
property MyProperty: integer read FMyProperty write FMyProperty
MyProperty 将在对象检查器中可见。
【讨论】:
已发布的属性将导出运行时类型信息 (RTTI)。
看看here 了解 Delphi 中的 RTTI
【讨论】:
运行时类型信息 (RTTI) 仅为 published 类成员生成。
【讨论】:
如您所述,公共属性和已发布属性具有相同的可见性。发布的属性包含在 RTTI 中,公共属性不包含。
【讨论】:
在运行时,已发布部分和公共部分中的条目可同等访问。
它们之间的主要区别在于组件的已发布项在设计时出现在对象检查器中。
发生这种情况是因为,对于已发布部分中的字段,RTTI 是自动生成的。
Object Inspector 选择它并使用它来识别要添加到其属性和事件列表中的内容。
【讨论】:
附带说明,已发布还有一个特别之处:
类成员的默认可见性是published,因此请检查以下不安全代码:
TTopSecret = class(TObject)
Name: string;
Password: string;
function DecryptPassword(const AValue): string;
public
constructor Create(const AName, AEncryptedPassword: string);
end;
Name、Password 和 DecryptPassword() 在“全球”可见。
【讨论】:
除了其他答案:
已发布的属性由流系统自动存储。
例如,如果您有一个 TComponent 的后代实例并使用 WriteComponent 将其写入 TStream,则所有 (好吧,不是全部,但这是另一个问题) 已发布的属性都将写入流中而没有任何进一步编码。
当然,流媒体系统只能这样做,因为 RTTI 可用于那些已发布的属性。
【讨论】:
似乎已经有很多好的答案,指出 Object INspector,RTTI, 等等。这些都是拼图的一部分。
如果去掉已发布的关键字,整个 Delphi RAD 工具设计将需要某种方式来指定哪些属性存储在 DFM 中,在组件属性检查器中检查,并且可以在运行时从 DFM 重新加载表单或创建数据模块。
总之,这就是 Published 的用途。令我感兴趣的是 QT 的设计者(最初是 TrollTech,后来成为诺基亚的一部分,后来仍然从 Digia 分拆出来)必须为他们的 C++ RAD 库“QT”模拟这种级别的 RTTI,添加一个“已发布”的等价物和一个“属性”等价物,而纯 C++ 仍然缺乏这种基本功能。
【讨论】: