自我分配任务的后果

3

今天我发现了一段代码,感觉有点不太好。

TMyObject.LoadFromFile(const filename: String);
begin
  if fileExists(filename) then
    self := TSomeObjectStreamer.ReadObjectFromFile(filename);
end;

如果这段代码能够正常工作,它至少会泄露一些内存,但是它是否有效呢?
以这种方式分配self是否可以?
如果流对象与原始的self不属于同一个子类,会怎样呢?
如果流对象是一个与原始的self没有共同祖先的不同类,会怎样呢?

1
可能是 https://dev59.com/9HRA5IYBdhLWcg3wzhbZ 的重复问题。 - gabr
在这个上下文中,你认为“works”的意思是什么?这段代码必须做什么才能让你认为它“工作正常”? - Rob Kennedy
当我阅读这段代码时,我猜测其意图是用从文件流中读取的新实例替换对象的一个实例。调用LoadFromFile()的调用者期望它所持有的TMyObject实例的引用现在指向一个新实例。 - Vegar
3个回答

6

2

考虑到一个方法等同于一个自由例程,它接受名为Self的对象作为其第一个参数:

TMyClass.MyRoutine({args})  <=>  MyRoutine(Self: TMyClass {; args})

考虑到这一点,您会发现您可以在不损坏原始对象的情况下本地更改Self的内容

但是您是正确的,这确实非常糟糕,并且很容易出错。

如果没有非常有说服力的注释,我不会接受这样的代码...


不知道为什么,你使用粗体让我的耳朵发麻。 - dummzeuch
@dummzeuch,这是对臭味代码的嘈杂警告!;-) - Francesca

1
是的,你可以将self作为一个本地临时变量使用,即使在这里它是多余的。 但是,在这种情况下,流对象必须与self(TMyObject)是同一类,否则编译器会检测到错误,因为类型不兼容。
在你的例子中,TSomeObjectStreamer.ReadObjectFromFile() 应该返回一个TMyObject,或者你的编译器应该发出警告(或抛出错误)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接