我有class字段
someList : TList<SomeInterFace>;我只需要在列表中存储对象并搜索它们,从来不想修改它们。所以我决定写
someList : TList<const SomeInterFace>;但是我有很多编译器错误。似乎不可能在标准的Delphi容器中存储const对象?
发布于 2021-10-27 19:01:39
const只有在方法的上下文中才有意义:
procedure DoSomethingWithInterface(const AInterface: SomeInterface)
begin
// do something
end;在这里,如果没有const声明,接口的引用计数在传入方法时会递增,在方法返回时会再次递减。使用const时,通过引用传递接口,但不修改引用计数。这之所以有效,是因为当您仍然在方法中时,接口的引用计数不可能下降,这样程序就可以将方法中的这种临时使用视为没有发生,从而节省了必须修改引用计数字段的开销。在here上有更多的阅读。
然而,在列表中存储引用是完全不同的事情,因为列表中对象的生命周期是不确定的。一个方法有明确的开始和结束,所以你对对象的引用的持续时间是有严格限制的-当你还在使用它时,不会有对象被删除的风险(尽管对共享变量或其他类似的并发错误进行了跨线程操作)。但是,在列表中,无法保证该引用将在列表中存在多长时间,因此您不能绕过递增引用计数。
此外,在方法中使用const的最大节省是编译器在方法周围生成一个隐式的try/finally块,否则将管理引用计数。在方法中使用const可以节省try/finally的开销,这是主要的性能增益。但是,在向列表添加字符串或接口引用时,不会生成这样的隐式代码,因为您作为开发人员,完全控制列表中引用的生命周期,这与传递给方法的参数不同,方法由编译器管理。
所以,总而言之,没有办法去做你提出的事情,但也没有必要去做你提出的事情。如果您绕过了列表中接口引用的引用计数,那么它们所指向的对象可能会在对它们的其余引用消失的任何时候被删除,而您最终会在列表中得到一个死引用。
https://stackoverflow.com/questions/69743819
复制相似问题