运算符重载时的参数问题
在C++中,当重载二元运算符时,运算符的左侧操作数对应于重载函数的第一个参数,而运算符的右侧操作数对应于重载函数的第二个参数。在你的例子中,operator*
函数被重载为接受一个整数和一个Complex
对象作为参数,这样整数就是运算符的左侧操作数,而Complex
对象是右侧操作数:
friend Complex operator*(int scalar, const Complex& c);
当调用这个重载的运算符时,例如:
Complex result = 3 * c;
这里,3
是整数,作为左侧操作数传递给operator*
函数,而c
是Complex
对象,作为右侧操作数传递。
如果重载的运算符只有一个参数,那么这个参数通常对应于运算符的右侧操作数。这是因为运算符的左侧操作数是通过this
指针隐式传递的,它指向调用运算符的对象。例如,如果你想要重载Complex
类的*
运算符来与一个整数相乘,你可以这样写:
class Complex {
public:
// ...
// 成员函数重载乘法运算符
Complex operator*(int scalar) const {
return Complex(scalar * real, scalar * imag);
}
};
在这个成员函数重载的例子中,整数参数是显式传递的,而Complex
对象(即this
指向的对象)是隐式传递的,因此整数是运算符的右侧操作数。这样的调用会是:
Complex result = c * 3;
这里,c
是Complex
对象,作为左侧操作数(通过this
指针),而3
是整数,作为右侧操作数显式传递给operator*
函数。
成员函数重载和非成员函数重载
在C++中,大多数运算符都可以通过成员函数或非成员函数(包括友元函数)进行重载。下面分别举一个成员函数重载和非成员函数重载的例子。
成员函数重载例子
假设我们有一个表示复数的类Complex
,我们想要重载加法运算符+
来允许两个Complex
对象相加。这可以通过成员函数来完成:
class Complex {
public:
double real, imag;
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// 成员函数重载加法运算符
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
};
int main() {
Complex c1(1.0, 2.0);
Complex c2(2.0, 3.0);
Complex c3 = c1 + c2; // 调用成员函数重载的+
return 0;
}
在这个例子中,operator+
是一个成员函数,它接受一个Complex
类型的参数other
,并返回一个新的Complex
对象,其real
和imag
分别是两个操作数的对应部分相加的结果。
非成员函数重载例子
现在考虑一个非成员函数重载的例子。假设我们想要重载二元运算符*
来允许一个整数和一个Complex
对象相乘。这可以通过非成员函数(可能是友元函数)来完成:
class Complex {
public:
double real, imag;
Complex(double r = 0.0, double i = 0.0) : real(r), imag(i) {}
// 非成员函数重载乘法运算符,可以是友元函数
friend Complex operator*(int scalar, const Complex& c);
};
// 非成员函数重载乘法运算符
Complex operator*(int scalar, const Complex& c) {
return Complex(scalar * c.real, scalar * c.imag);
}
int main() {
Complex c(1.0, 2.0);
Complex result = 3 * c; // 调用非成员函数重载的*
return 0;
}
在这个例子中,operator*
是一个非成员函数,它接受一个整数和一个Complex
类型的参数,并返回一个新的Complex
对象,其real
和imag
分别是整数与Complex
对象的对应部分相乘的结果。由于这个函数不是Complex
类的成员,我们需要将它声明为Complex
类的友元,以便它可以访问Complex
对象的私有成员。
这两种重载方式(成员函数和非成员函数)都可以用来重载运算符,选择哪一种取决于运算符的语义和操作数的类型。