常量对象不能作为var参数传递 [英] Constant object cannot be passed as var parameter

查看:169
本文介绍了常量对象不能作为var参数传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是故障代码。

multresult := mult(mult(temp, quatview), conjugate(temp));

完整过程

procedure TForm2.RotateCamera(var angle: Single; x: Single; y: Single; z: Single);
var
    temp, QuatView, multResult : TQuaternion;
begin
    temp.x := x * sin(Angle/2);
    temp.y := y * sin(Angle/2);
    temp.z := z * sin(Angle/2);
    temp.w := cos(Angle/2);

    quatview.x := camera1.Position.x;
    quatview.y := camera1.Position.y;
    quatview.z := camera1.Position.z;
    quatview.w := 0;

    multresult := mult(mult(temp, quatview), conjugate(temp));

    camera1.Position.x := multresult.x;
    camera1.Position.y := multresult.y;
    camera1.Position.z := multresult.z;
end;

多重功能

function TForm2.mult(var A: TQuaternion; B: TQuaternion) :TQuaternion;
 var
   c : TQuaternion;
begin
  C.x := A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y;
  C.y := A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x;
  C.z := A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w;
  C.w := A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z;
result := C;
End;

和共轭

 function TForm2.conjugate( var quat:TQuaternion) :TQuaternion;
  begin
     quat.x := -quat.x;
     quat.y := -quat.y;
     quat.z := -quat.z;
     result := quat;
  end;

以及如果需要的话,四元组

and if needed TQuaternion

type
  TQuaternion = class
    x: single;
    y: single;
    z: single;
    w: single;
  end;

我为什么会收到此错误以及如何解决该错误?

any idea why i get this error and how to fix it?

推荐答案

对您所提问题的答案是,mult的参数应为const。您无需修改​​它们(也不应修改),因此请将它们设为const。然后,您的代码将编译。

The answer to the question you asked is that the parameters to mult should be const. You don't modify them (and you should not), so make them const. Then your code compiles.

类似地,Conjugate修改其输入参数也是一种不好的形式。这使该功能难以使用。

In a similar vein, it's bad form for Conjugate to modify its input parameter. That makes the function horrid to use. Don't do that.

请考虑以下内容:

multresult := mult(mult(temp, quatview), conjugate(temp) );

由于共轭会改变温度,因此您最好希望在其他用途​​之后再调用共轭临时的语言不提供此类保证。因此,请全力以赴!

Since conjugate modifies temp, you'd better hope that the call to conjugate is made after the other use of temp. The language makes no such guarantee. So, cross your fingers!

算术代码值得遵循的原则之一是:永远不要修改输入参数/操作数,并且函数始终返回 new 值。遵循这一原则,您将永远不会陷入上面突出显示的陷阱。

One of the principles worth following with arithmetic code is that input parameters/operands should never be modified, and that functions always return new values. Follow this principle and you'll never fall into trap highlighted above. See the second part of my answer for an illustration.

但是,即使进行了这些更改,代码也无法正常工作,因为您没有实例化TQuaternion类的任何实例。您确定不是记录吗?

However the code won't work even with these changes because you are not instantiating any instances of the TQuaternion class. Are you sure that it's not a record?

创建好的四元数类型会带来真正的进步。这应该是一个值类型,因为出于多种原因,算术运算更适合于值类型。

The real forward progress will come when you create a good quaternion type. This should be a value type since arithmetic operations are better suited to value types for a number of reasons.

在现代的Delphi中,您希望将记录与运算符一起使用。这是您需要的一种口味,可以根据需要进行扩展。

In modern Delphi you want to use a record with operators. Here's a flavour of what you need, ready to extend as you need.

type
  TQuaternion = record
    x: single;
    y: single;
    z: single;
    w: single;
    function Conjugate: TQuaternion;
    class operator Multiply(const A, B: TQuaternion): TQuaternion;
  end;

function TQuaternion.Conjugate: TQuaternion;
begin
  Result.x := -x;
  Result.y := -y;
  Result.z := -z;
  Result.w := w;
end;

class operator TQuaternion.Multiply(const A, B: TQuaternion): TQuaternion;
begin
  Result.x := A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y;
  Result.y := A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x;
  Result.z := A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w;
  Result.w := A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z;
end;

使用这种类型,您的乘法调用变为:

With this type your multiplication call becomes:

 multresult := temp*quatview*temp.Conjugate;

您肯定会为此类型编写更多的运算符和辅助函数。

You'll surely want to write more operators and helper functions for this type.

将算术函数移入此类型并移出表单非常重要。不要使用高级GUI表单类来实现低级算术。

It's really important to move the arithmetic functions into this type and out of your form. Don't use your high level GUI form class to implement low level arithmetic.

最后一条建议。您的代码重复使用了var参数。我建议您将var参数视为要避免的事情。如果可能,尝试在没有它们的情况下编写代码。

One final piece of advice. Your code has repeated mis-use of var parameters. I suggest you treat var parameters as things to be avoided. Try to write code without them if possible.

这篇关于常量对象不能作为var参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆