我处理我们软件的标准数据类。这是当前状态的最小示例:
TDataOne = (Width, Length, Height);
TDataTwo = (Diameter, Weight);
TDatStruct = class;
TDatSubStructOne = class(TDatStruct)
public
myData : array[TDataOne] of double;
procedure writeToFile(AFileName : string);
end;
TDatSubStructTwo = class(TDatStruct)
public
myData : array[TDataTwo] of double;
procedure writeToFile(AFileName : string);
end;
为了减少代码冗余,我想在TDatStruct
中设想一个具有共同写入功能的数据结构。挑战(至少对于业余爱好者来说)是:
mydata
的大小可变,具体取决于子结构,并基于不同的枚举类型mydata
我唯一的想法(忽略第3点)是将子结构的数组数据作为开放数组参数传递给公共写入过程,如:
writeToFile(AFileName : string; writeData : array of double);
有没有办法将动态数组与枚举类型或虚拟枚举数组相结合?还是我完全走错了路?
答案 0 :(得分:4)
mydata的大小可变,具体取决于子结构,并基于不同的枚举类型
Delphi具有内在函数Low和High
您不需要知道数组的大小。
我仍然希望在子结构中使用枚举类型访问mydata
使用succ
和pred
内在方法遍历枚举。
由于实际代码中不同数组的数量,我不想将子结构数据作为参数传递给公共写入函数
你的所有阵列看起来都一样......
它们只是array of double
,虽然元素数量不同。
您可以像这样实施writeToFile
:
procedure writeArrayToFile(const AFileName : string; const writeData : array of double);
var
i: integer;
begin
for i:= low(writeData) to High(writeData) do begin
WriteADoubleToFile(AFilename, writeData[i]);
end; {for i}
end;
注意使用const
如果你不使用它,数组将被复制到堆栈中,导致大数组的大量延迟。
如果数组是您的类的数据成员,那么您可以简单地编写代码:
procedure TDatStruct.writeToFile(const AFileName : string);
begin
WriteArrayToFile(FileName, GetMyData^);
end;
请注意,因为父类TDatStruct
实际上没有任何数据,所以您需要编写一个可以获取该数据的虚函数。
type
TMyArray = array[0..0] of double;
PMyArray = ^TMyArray;
.....
TDatStruct = class
protected
function GetMyData: PMyArray; virtual; abstract;
public
procedure WriteToFile(const Filename: string); //no need for virtual
end;
WriteArrayToFile
的{{3}}会为您解决问题。
请注意writeToFile
中的数组参数是“开放数组参数”,这将接受静态和动态数组。
如果你使用不同种类的数组(双/字符串等) 然后使用通用方法。
有没有办法将动态数组与枚举类型或虚拟枚举数组相结合?还是我完全走错了路?
动态数组具有可变数量的元素 您无法直接使用枚举对其进行索引 但是,您可以使用open array parameter内在函数将枚举值转换为整数 它也适用于超过256个值的枚举。 文档不正确,会根据需要返回字节,单词或基数。
function FixedArrayToDynamicArray(const input: array of double): TArray<double>;
begin
//translate a fixed array to a dynamic array.
SetLength(Result, High(input));
Move(input[0], Result[0], SizeOf(Double) * High(input));
end;
代码前的泛型代码:
type
TDoubleArray = array of double;
function FixedArrayToDynamicArray(const input: array of double): TDoubleArray;
... same from here on.
答案 1 :(得分:0)
有许多不同的方法,很难说出你的情况最好的方法。
当然,WriteToFile
应该在TDatStruct
中作为摘要引入:
TDatStruct = class
public
procedure WriteToFile(AFileName: string); virtual; abstract;
和后代应该以不同的方式实现它:
TDatStructOne = class (TDatStruct)
...
public
procedure WriteToFile(AFileName: string); override;
以这种方式,您可以拥有类TDatStruct的对象,它实际上可以是TDatStructOne或TDatStructTwo,但使用它的代码并不需要知道它处理的内容:基本多态性
在这种情况下,您对用于在每个类中存储信息的数据类型有很多自由,实现可能会有所不同。最简单的是:
TDatStructOne = class (TDatStruct)
public
Width: Double;
Length: Double;
Height: Double;
procedure WriteToFile(AFileName: string); override;
end;
TDatStructTwo = class (TDatStruct)
public
Diameter: Double;
Weight: Double;
procedure WriteToFile(AFileName: string); override;
end;
并且在WriteToFile
每个后代都有自己的工作。
所以,通过你的挑战:
obj.SaveToFile(FileName)
并将相应保存。