gpt4 book ai didi

delphi - 如何从TFileStream和TMemoryStream继承?

转载 作者:行者123 更新时间:2023-12-03 15:16:17 26 4
gpt4 key购买 nike

我有一个从TFileStream继承的类和一个从TMemoryStream继承的类。两者实现与读取数据完全相同的功能,例如:

TCustomFileStream = class (TFileStream)
function ReadByte: byte;
function ReadWord: word;
function ReadWordBE: word;
function ReadDWord: longword;
function ReadDWordBE: longword;
function ReadString(Length: integer): string;
function ReadBlockName: string;
etc


当我想编写一个可以将两种类型的流作为参数的函数时,我必须使用TStream:

function DoStuff(SourceStream: TStream);


当然,这意味着我无法使用自定义功能。
解决这个问题的最佳方法是什么?理想情况下,我希望能够有一个适用于FileStream或MemoryStream的Tst​​ream兼容类,因此我可以执行以下操作,并且该流是FileStream还是MemoryStream都无关紧要:

function DoStuff(SourceStream: TMyCustomStream);
begin
data := SourceStream.ReadDWord;
otherData := SourceStream.Read(Buffer, 20);

end;

最佳答案

在实际问题标题中回答问题:您不能。 :)

但是,如果我们退后一步,看看您尝试解决的问题:


  我有一个继承自TFileStream的类和一个
  从TMemoryStream继承。两者实现完全相同的功能
  与读取数据有关


我认为您误报了您的问题,并正确地重新指出了您需要的答案。 :)

I have some structured data that I need to read from different sources (different stream classes).


流只是一堆字节。这些字节中的任何结构都取决于您如何读取/写入流。即在这种情况下,“如何”体现在您的职能中。涉及的具体流类是TFileStream和TMemoryStream的事实从根本上来说并不是问题的一部分。解决TStream的问题,然后为所有TStream派生类(包括您现在正在处理的类)解决。

流类应基于它们如何需要在特定位置(内存,文件,字符串等)之间读取/写入字节而不是在这些字节中的任何特定结构的方式进行专门化。

您真正需要的是一个类,该类封装了所涉及数据的结构知识,并且能够将其应用于任何流,而不必创建专门的流类来重复结构的知识。

读者班

一种解决方法(最好的?)是实现一个封装所需行为的类。例如在“阅读器”类中。

TStuffReader = class
private
fStream: TStream;
public
constructor Create(aStream: TStream);
function ReadByte: byte;
function ReadWord: word;
function ReadWordBE: word;
function ReadDWord: longword;
function ReadDWordBE: longword;
function ReadString(Length: integer): string;
function ReadBlockName: string;
end;


此类还可能还提供用于写入流的函数(在这种情况下,您可以将其称为TStuffFiler,因为它不仅是一个读取器),或者您可能还有一个单独的用于编写流的类,称为TStuffWriter(对于例)。

无论您选择实现它,此阅读器类都将能够从任何TStream派生类读取(和/或写入)该结构化数据。对于这些功能,涉及什么特定的流类别无关紧要。

如果您的问题包括需要将对流的引用传递给各种函数等,则应将对引用的传递传递给阅读器类。读取器必定带有对所涉及流的引用,但是先前您认为需要在专用流类上调用函数的代码仅使用读取器函数。如果该代码也需要访问流本身,则读者可以在必要时公开它。

然后在将来,如果您发现自己需要从其他流类中读取此类数据(例如,如果您发现自己从数据库中检索数据,则为TBLOBStream),您的TStuffReader(或任何您选择调用的对象)可以直接进入并执行为您完成这项工作,而无需您做任何进一步的工作。

非替代类助手

类助手似乎提供了一种近似“多重继承”的机制,但应避免使用。它们从未打算在应用程序代码中使用。

VCL中存在类帮助程序,这与您所期望的完全一样,因为它们旨在用于框架和库中,并且VCL是框架库,因此在这里使用它与该用法完全一致。

但这并不表示它们适合在应用程序代码中使用,并且文档仍在强制执行这一点。


  类和记录助手提供了扩展类型的方法,但是它们
  在开发新产品时不应被视为要使用的设计工具
  码。对于新代码,您应该始终依靠常规的类继承
  和界面实现。


该文档对于适用于班级助手的限制也很清楚,但没有明确解释为什么这些限制会导致问题,这也许就是为什么某些人仍然坚持认为它们适合使用的原因。

covered these problems in a blog post不久就被引入了(今天同样的问题仍然适用)。实际上,我写了 a number of posts covering the topic就是这样一个问题。

似乎不愿放弃这样一种观念,即只要您对帮手保持谨慎,就不会遇到问题,这就是无视这样一个事实,即无论您多么谨慎,使用帮手都可以如果最终与他人共享代码,则被其他人同样谨慎使用所破坏。

在Delphi中,没有比VCL本身更多的共享代码。

在VCL中使用(附加)助手将使您自己的助手遇到麻烦的可能性更大,而不是更少。即使您的代码在一个版本的VCL中与您自己的助手完美配合,下一个版本也可能会破坏事情。

在VCL中它们的泛滥并没有被建议更多地使用,它只是您应该避免使用它们的一个很好的理由。

关于delphi - 如何从TFileStream和TMemoryStream继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39229192/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com