假设我有一张唱片TQuaternion和一张唱片TVector。四元数有一些具有TVector参数的方法。另一方面,TVector支持一些具有TQuaternion参数的操作。
知道Delphi(Win32)不允许转发录音声明,我该如何优雅地解决这个问题?
在这里使用类不是一个真正的选项,因为我真的想使用运算符重载来处理这种罕见的情况,它实际上很有意义。
现在我只是简单地将这些特定的方法从记录中移出,转移到单独的函数中,这是一种很好的老式方法。更好的建议是最受欢迎的。
答案 0 :(得分:3)
一般来说,没有优雅的解决方案,只有像这样的无类型引用的旧hacks:
type
TVector = record
procedure UseQuaternion(var Q);
end;
TQuaternion = record
procedure UseVector(var V: TVector);
end;
{ TVector }
procedure TVector.UseQuaternion(var Q);
var
Quaternion: TQuaternion absolute Q;
begin
Quaternion.UseVector(Self);
end;
{ TQuaternion }
procedure TQuaternion.UseVector(var V: TVector);
begin
end;
对于特定情况,以下模式可能有用:
type
TVectorData = array [0..1] of Double;
TQuaternionData = array [0..3] of Double;
TVector = record
Data: TVectorData;
procedure UseQuaternion(var Q: TQuaternionData);
end;
TQuaternion = record
Data: TQuaternionData;
procedure UseVector(var V: TVector);
end;
答案 1 :(得分:3)
如果操作员不是实际问题,您可以使用记录助手解决此问题。
type
TVector = record
end;
TQuaternion = record
procedure UseVector(var V: TVector);
end;
TVectorHelper = record helper for TVector
procedure UseQuaternion(var Q: TQuaternion);
end;
这将仅解决循环依赖关系,并且它不适用于运算符。它还有一个缺点,就是你不能为TVector提供任何其他记录助手,至少不能在同一个地方都有这两个记录助手。
答案 2 :(得分:2)
我认为你的“老式”解决方案更好 作为替代解决方案 - 但导致您的解决方案的架构 - 如何将包含您的两条记录的记录和作为主记录方法的方法:
type
TQuaternionVector = record
Vector: TVector;
Quaternion: TQuaternion;
procedure F(V: TVector; Q: TQuaternion);
end;
答案 3 :(得分:1)
对于想要使用运算符重载的特定情况(甚至更具体地说,是二元运算符),可以按任意顺序指定要操作的记录类型。
下面的声明将允许您以任意组合添加向量和四元数(如果有意义:-))(TQuaternion的第3个添加声明是有趣的):
type
TVector = record
class operator Add( v1, v2 : TVector ) : TVector;
end;
TQuaternion = record
class operator Add( q1, q2 : TQuaternion ) : TQuaternion;
class operator Add( q : TQuaternion; v : TVector ) : TQuaternion;
class operator Add( v : TVector; q : TQuaternion ) : TQuaternion;
end;
假设适当的变量声明,以下所有编译:
q1 := q2 + q3;
v1 := v2 + v3;
q1 := q2+v2;
q2 := v2+q2;
这足以满足您的需求吗?