重载 * 乘法运算符两次作为成员函数

Overloading * multiplication operator twice as a member function?

本文关键字:两次 函数 成员 运算符 重载      更新时间:2023-10-16

向下滚动查看TL:DR。

这个问题与这个问题类似,但有一些不同之处。它涉及将*运算符重载两次,用于一个名为jVector的类,它只表示一个二维笛卡尔向量。

第一种乘法是jVector * jVector,或点积。第二种类型是乘以实数,double * jVector 。这只返回一个向量,其条目乘以双精度

以下是一些代码来说明我正在尝试执行的操作:

class jVector{
    public:
        double x, y;
        jVector(double x_val = 0., double y_val = 0.){
            x = x_val;
            y = y_val;
        }
        //Operator overload functions
        //[...]
        //F1: Dot product (WORKS)
        double operator* (jVector& factor){
            double result;
            result = x * factor.x;
            result += y * factor.y;
            return result;
        }
        //F2: Real number multiplication (DOES NOT WORK)
        jVector operator* (double f){
            jVector result;
            result.x = x * f;
            result.y = y * f;
            return result;
        }
        //[...]
}
//F3: As a non-member (WORKS)
jVector operator* (double f, jVector V){
    jVector result;
    result.x = V.x * f;
    result.y = V.y * f;
    return result;
}

三个相关功能分别标有F1F2F3。函数F2F3永远不会同时定义(我注释掉其中一个以测试另一个(。

这是尝试表达类似 2.0 * Foo 的结果,其中 FoojVector 类型的向量。使用 F3 时,该操作按预期工作,该函数在类外部定义。但是,当仅使用成员函数F2时,会引发一个错误,指出no match for 'operator*' in '2 * Foo'

这与根本不重

载运算符时遇到的错误类型相同,这表明我没有正确定义F2,或者F2F1冲突。

相当确定我的问题与我之前提到的问题不同,因为F1F2有不同的返回类型和参数类型。

TL:DR

所以我的问题来了:为什么我可以重载*两次,只要其中一个被定义为非成员函数?为什么两个重载函数都不能是类的成员?

它不能作为成员函数工作,因为您的 F2 替代项将jVector作为第一个操作数 ALWAYS(它是一个成员函数,因此您无法选择第一个参数是什么 - 它是jVector *this [被语言隐藏](。编译器理论上可以允许两个操作数交换位置(它可以x * 2.0转换为常规数学运算的2.0 * x,但由于运算符重载不是为了"交换",如果编译器确实重新排列它们,那不是很好(

double第一个操作数,你需要一个独立的函数。

对于成员函数运算符重载,第一个操作数必须是类的对象。 重载函数的参数是第二个操作数。所以:

double operator* (double f){

仅适用于您正在执行a_vector * a_double的情况,而不适用于a_double * a_vector

出于这个原因(和其他原因(,通常最好对重载运算符使用非成员函数。 我建议这样做的方法是:

// member function
jVector & jVector::operator*=( double f )
{
    x *= f;
    y *= f;
    return *this;
}
// free functions
jVector operator* (double f, jVector V) { return V *= f; }
jVector operator* (jVector V, double f) { return V *= f; }