向下滚动TL:DR。
此问题与this类似,但有一些差异。它涉及为名为*
的类重载jVector
运算符两次,它只是表示二维笛卡尔向量。
第一种乘法是jVector * jVector
或dot product。第二种类型乘以实数double * jVector
。这只是返回一个向量,其条目乘以double。
以下是一些代码来说明我正在尝试做的事情:
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;
}
三个相关功能标记为F1
,F2
和F3
。函数F2
和F3
永远不会同时定义(我会注释掉其中一个来测试另一个)。
以下是尝试表达2.0 * Foo
之类的结果,其中Foo
是jVector
类型的向量。使用F3
时,该操作按预期工作,该函数在类外定义。但是,当仅使用成员函数F2
时,会出现一个错误no match for 'operator*' in '2 * Foo'
。
如果您根本不重载运算符,则会出现相同类型的错误,表明我没有正确定义F2
,或者F2
与{{1}冲突}}
我非常确定我的问题与前面question I mentioned中的问题不同,因为F1
和F1
具有不同的返回类型和参数类型
TL:DR
所以这是我的问题:为什么我能够重载F2
两次,只要其中一个被定义为非成员函数?为什么两个重载函数都不能成为类的成员?
答案 0 :(得分:2)
对于成员函数运算符重载,第一个操作数必须是该类的对象。重载函数的参数是第二个操作数。所以:
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; }
答案 1 :(得分:2)
它没有作为成员函数工作,因为你的F2替代方案需要jVector
作为第一个操作数总是(它是一个成员函数,所以你不能选择什么第一个参数是 - jVector *this
[由语言隐藏])。理论上,编译器可以允许两个操作数交换位置(可以x * 2.0
转换为2.0 * x
进行常规数学运算,但由于操作符重载不能被交换围绕",如果编译器DID重新安排它们,这将不是很好)
对于第一个操作数为double
,您需要一个独立的功能。