在包含WideString的记录指针中使用New/Dispose

5

我有非常老的代码(来自D3):

TMyRecord  = record
  Index   : Integer;
  Header  : String[70];
  Strings : Array[1..MAX_VALUES] of String[70];
end;

TMyClass = class(TComponent)
  FData  : ^TMyRecord;
  ...
end;

constructor TMyClass.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  New(FData);     
  ...
end;

destructor TMyClass.Destroy;
begin
   Dispose(FData);
   inherited;
end;

问:将String[70]替换为WideString;,并将Array[1..MAX_VALUES] of String[70]替换为Array[1..MAX_VALUES] of WideString是否安全?(请解释原因)

我需要在Delphi 7中支持Unicode。


你为什么想要改变它? - LU RD
“Dispose” 调用 “_Finalize” 程序,正确释放所有内部结构。你打算如何使用这种类型? - MBo
4
简单的回答是“是”。这是一种托管类型,NewDispose函数用于初始化和终止托管类型。 - David Heffernan
1个回答

7
一般情况下,您不应使用 WideString。它仅用于与 COM BSTR 的兼容性。
但是,如果您使用的是 2009 年之前的版本且需要 Unicode,则没有选择。 WideString 是动态分配的,当您使用 new 记录时,Delphi 将添加代码以初始化字符串。 您不必自己初始化它们。
就像短字符串一样,WideString 不是引用计数的,但是它们将在您 dispose 记录时被销毁。 如果您将 WideString 分配给另一个 WideString,Delphi 将进行复制,这比引用计数略微低效,但否则没有问题。
每当 WideString 超出范围时,它都会被销毁。
注意,虽然 Delphi 7 支持使用 WideString 进行 Unicode,但 VCL 无法显示您的 WideString,它只能显示 AnsiString。 如果要显示 WideStrings,请使用 TNT 组件,有关更多信息,请参见此答案:Handling a Unicode String in Delphi Versions <= 2007 如果要将 WideString 分配给 (Ansi)string,那么最好使用 plain string,因为您将失去所有 Unicode。 您可以使用 UTF8,但 D7 也无法显示 UTF8。
进一步注意事项:在亚洲语言环境中进行索引时,MyWidestring[i] 不一定表示第 i 个字符,因为 Unicode 无法完全用 2 个字符表示。 除非您使用亚洲语言,否则这不会影响您。
问:将 String[70] 替换为 WideString 是否安全?
是的,但更容易将 String[70] 替换为 String(也称为 AnsiString)。因为 D7 VCL 支持 AnsiString 而不支持 WideString。 除此之外,您真的没有问题。
进一步阅读:https://grahamwideman.wikispaces.com/Delphi+String+Types

谢谢。你说的“要小心PWideChar”,是什么意思?如果我使用Windows.ExtTextOutW(Handle, X, Y, TextFlags, nil, PWideChar(WideText)...,我应该担心吗? - zig
没事。只有在指向的字符串已经超出作用域后,你才会遇到问题,而且只要你持续使用P(Wide)Chars。 - Johan

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