【问题标题】:C++ Calling an overloaded operator (static) from a member function [closed]C ++从成员函数调用重载运算符(静态)[关闭]
【发布时间】:2026-01-16 08:55:02
【问题描述】:

所以我在实现自己的四元数类时遇到了一个从成员函数调用我的一个运算符(静态)函数时没有预料到的问题。见函数rotateByVector()

class Quaternion
{
    public:

        double x, y, z, w;

        Quaternion(double w, double xi, double yj, double zk)
        {
            w = w;
            x = xi;
            y = yj;
            z = zk;
        }

        Quaternion operator +(Quaternion q1, Quaternion q2)
        {
            return Quaternion(q1.w + q2.w, q1.x + q2.x, q1.y + q2.y, q1.z + q2.z);
        }

    Quaternion operator*(Quaternion q1, Quaternion q2)
    {
        return Quaternion(q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z
            , q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y
            , q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z
            , q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x);
    }

    void rotateByVector(double x1, double y1, double z1, double[3] res)
    {
        // want to calculate Hamilton Product
        // res_quaternion = this_quaternion * quaternion_vector(0, x1, y1, z1) * this_conj;
        // return double[3] {res_quaternion.x, res_quaternion.y, res_quaternion.z}

        Quaternion q = Quaternion(0.0f, x1, y1, z1);
        Quaternion r = (*this).operator*() q; //doesn't like it
        Quaternion r = this->operator*(q); //doesn't like it either
        ...
        r = r * this.conj();
        res[0] = r.x;
        res[1] = r.y;
        res[2] = r.z;
    }

}

我应该如何实现this quaternion乘以参数的一乘以this quaternion的共轭的乘法

我知道我很了解,但我肯定错过了一些东西。

【问题讨论】:

  • this.conj(); 不是一个东西。 operator*() 在哪里?请贴出真实代码。
  • (*this).operator*() q 你想在这里使用运算符重载将你的 2 个类对象相乘吗??
  • 您显示的是+ 运算符,但您使用的是* 运算符。请edit您的问题与minimal reproducible exampleSSCCE (Short, Self Contained, Correct Example)
  • 另外,您正在返回一个指向局部变量的指针:return double[3] { r.X, r.Y, r.Z };
  • 而且您还声明了一个静态运算符重载,这是非法的。该代码有十种无法编译的方式。

标签: c++


【解决方案1】:

因此,当您在问题中重载运算符时,您可以编写此 ::

Quaternion operator*(Quaternion q1, Quaternion q2)因为这是一个成员函数,你应该把它改成这个

(1) Quaternion operator*(Quaternion q2)

或者可能使用朋友功能,例如

(2) friend Quaternion operator*(Quaternion q1, Quaternion q2)

所以,当你想将你的 2 个 Quaternion 对象相乘并使用 (1) 中提到的声明时,可能像这样 ::

Quaternion a, b, c;
c = a*b;

您的调用 a*b 以某种方式转换为 a.operator*(b) 本身,因此您不必显式调用 Quaternion r = a.operator*(b); (就像我在您的代码中看到的那样) 在operator 函数中,您可以使用this 指针访问a 的成员,因为您对函数operator*() 的调用是在对象a 上调用的。

这就是运算符重载的意义所在!我们在对象之间使用普通运算符而不是调用函数。

在使用(2)声明时,你使用了friend,朋友不是成员函数,但它可以访问私有数据成员,所以当你使用声明时(2) 你为计算中涉及的两个对象传递了 2 个参数,因为这次函数没有在任何对象上调用!

您还可以考虑从运算符重载函数中返回对象的引用,这将帮助您实现像 (a+b+c) 这样的关联性。

就像把你的声明改成这样::

Quaternion& operator*(Quaternion q2)

friend Quaternion& operator*(Quaternion q1, Quaternion q2)

希望这能有所帮助!

试试看这个 :: Operator overloading (它详细解释了一切!)

【讨论】:

  • 你的意思是让函数返回Quaternion& ?
  • 会试一试并回复您。感谢您实际回答问题,而不是从中挑选漏洞。我在旅途中从一些 c# 中编写了代码。因此指针错误。
  • 没关系!!好吧,更改返回类型实际上不会消除您的编译错误,如果您尝试将 2 个对象相乘,还可以考虑将您的语句 Quaternion r = (*this).operator*() q; 更改为 Quaternion r = (*this) * q;