一.类运算符重载
1.
#include <iostream>
using namespace std;
class Complex {
private:
double r, i;
public:
Complex(double R = 0, double I = 0) : r(R), i(I) {};
Complex operator+(Complex b);
Complex operator-(Complex b);
Complex operator*(Complex b);
Complex operator/(Complex b);
void display();
};
Complex Complex::operator+(Complex b) { return Complex(r + b.r, i + b.i); }
Complex Complex::operator-(Complex b) { return Complex(r - b.r, i - b.i); }
//求复数相乘的算法
Complex Complex::operator*(Complex b) {
Complex t;
t.r = r * b.r - i * b.i;
t.i = r * b.i + i * b.r;
return t;
}
//求复数相除的算法
Complex Complex::operator/(Complex b) {
Complex t;
double x;
x = 1 / (b.r * b.r + b.i * b.i);
t.r = x * (r * b.r + i * b.i);
t.i = x * (i * b.r - r * b.i);
return t;
}
void Complex::display() {
cout << r;
if (i > 0)
cout << "+";
if (i != 0)
cout << i << "i" << endl;
//}display();
};
int main(void) {
Complex c1(1, 2), c2(3, 4), c3, c4, c5, c6;
Complex a, b(2, 3);
a = b + 2; //正确
// a=2+b; //错误
a.display();
c3 = c1 + c2;
c4 = c1 - c2;
c5 = c1 * c2;
c6 = c1 / c2;
c1.display();
c2.display();
c3.display();
c4.display();
c5.display();
c6.display();
return 0;
}
2..Complex(double R = 0, double I = 0) : r(R), i(I) {};与 Complex(double R = 0, double I = 0) {r=R ;i=I;}等价吗
这两段代码不完全等价。
第一段代码是使用成员初始化列表来初始化类的成员变量 r
和 i
。这是 C++ 中的一种初始化方式,可以在构造函数中使用它来指定如何初始化类的成员变量。在这种情况下,构造函数会将参数 R
和 I
的值分别传递给成员变量 r
和 i
。
第二段代码是在构造函数中使用赋值运算符来初始化类的成员变量。在这种情况下,构造函数会将参数 R
和 I
的值分别赋给局部变量 R
和 I
,然后再将这些局部变量的值赋给成员变量 r
和 i
。
这两段代码的主要区别在于初始化的方式。成员初始化列表可以直接将参数的值传递给成员变量,而赋值运算符则需要先创建局部变量,然后再将局部变量的值赋给成员变量。在性能方面,成员初始化列表通常比赋值运算符更高效,因为它可以直接将参数的值传递给成员变量,而不需要创建额外的局部变量。
因此,这两段代码不完全等价,推荐使用成员初始化列表来初始化类的成员变量。
3.Complex Complex::operator+(Complex b) { return Complex(r + b.r, i + b.i); }和 Complex Complex::operator+(Complex b,Complex c) { return Complex(r + b.r, i + b.i); }有什么区别?
这两个函数在功能上非常相似,都是实现两个复数的加法。然而,它们的参数列表是不同的。
第一个函数只有一个参数,即另一个Complex
对象b
。它返回的是当前对象(this
)和b
的加法结果。
第二个函数有两个参数,即两个Complex
对象b
和c
。它返回的是b
和c
的加法结果。
因此,这两个函数的主要区别在于它们接收的参数数量和类型。第一个函数只接收一个Complex
对象作为参数,而第二个函数接收两个Complex
对象作为参数。
另外,注意到在你的代码中,无论哪个函数,它们都使用了相同的返回类型和构造函数的参数。这意味着,你可以将加法的结果封装在一个新的Complex
对象中并返回。
4.为什么上述代码里使用a=2+b会报错
上述代码中,如果使用a=2+b
会报错,是因为把2当成了int类型,所以改成(Complex)2即可。
二.操作符重载与友元关系
1.
#include <iostream>
class Complex {
private:
double r, i;
public:
Complex(double R = 0, double I = 0) : r(R), i(I) {};
friend Complex operator+(Complex a, Complex b);
friend Complex operator-(Complex a, Complex b);
friend Complex operator*(Complex a, Complex b);
friend Complex operator/(Complex a, Complex b);
friend Complex operator+(Complex a, double b) {
return Complex(a.r + b, a.i);
}
friend Complex operator+(double a, Complex b) {
return Complex(a + b.r, b.i);
}
void display();
};
Complex operator+(Complex a, Complex b) {
return Complex(a.r + b.r, a.i + b.i);
}
Complex operator-(Complex a, Complex b) {
return Complex(a.r - b.r, a.i - b.i);
}
Complex operator*(Complex a, Complex b) {
Complex t;
t.r = a.r * b.r - a.i * b.i;
t.i = a.r * b.i + a.i * b.r;
return t;
}
Complex operator/(Complex a, Complex b) {
Complex t;
double x;
x = 1 / (b.r * b.r + b.i * b.i);
t.r = x * (a.r * b.r + a.i * b.i);
t.i = x * (a.i * b.r - a.r * b.i);
return t;
}
void Complex::display() {
std::cout << r;
if (i > 0)
std::cout << "+";
if (i != 0)
std::cout << i << "i" << std::endl;
}
int main(void) {
Complex c1(1, 2), c2(3, 4), c3, c4, c5, c6;
Complex a, b(2, 3);
Complex a1 = b + 2;
Complex a2 = 2 + b;
a1.display();
a2.display();
c3 = c1 + c2;
c4 = c1 - c2;
c5 = c1 * c2;
c6 = c1 / c2;
c1.display();
c2.display();
c3.display();
c4.display();
c5.display();
c6.display();
return 0;
}
这个更像我们平时理解的加减乘除关系。而且支持不同类型之间的运算。
三.=运算符重载
// 引入iostream库,这个库让我们可以使用cin和cout来进行输入和输出。
#include <iostream>
// 使用命名空间std,这样可以让我们使用标准库中的符号,而不用加std::前缀。
using namespace std;
// 定义一个名为X的类。
class X {
public:
// 重载赋值运算符。这是成员函数,因此它的第一个参数是隐式的类实例引用。
// 参数是常量引用,这意味着我们只能通过这个引用访问常量对象,不能修改它。
X &operator=(const X &x) {
// 输出字符串"a:",表示我们正在使用重载的赋值运算符。
cout << "a:";
// 返回当前对象的引用。这是非常重要的,因为它允许链式赋值。
return *this;
};
};
// 主函数,程序的执行从这里开始。
int main() {
// 创建三个X类的对象。
X obj1, obj2, obj3;
// 使用重载的赋值运算符将obj2的值赋给obj1。这会调用我们之前定义的赋值运算符函数。
obj1 = obj2; //调用重载“=”
// 使用成员函数语法再次调用赋值运算符。
obj1.operator=(obj2); //调用重载“=”
// 同时将obj3的值赋给obj2和obj1,也是调用我们重载的赋值运算符。
obj1 = obj2 = obj3; //调用重载“=”
return 0; // 返回0表示程序正常结束。
}
四. []与() 运算符重载
#include <iostream>
using namespace std;
class X {
public:
int operator()(int i = 0) {
cout << "X::operator(" << i << ")" << endl;
return i;
};
int operator()(int i, int j) {
cout << "X::operator(" << i << "," << j << ")" << endl;
return i;
};
int operator[](int i) {
cout << "X::operator[" << i << "]" << endl;
return i;
};
int operator[](char *cp) {
cout << "X::operator[" << cp << "]" << endl;
return 0;
};
};
int main(void) {
X obj;
int i = obj(obj(1), 2);
int a = obj[i];
int b = obj["abcd"];
cout << "a=" << a << endl;
cout << "b=" << b << endl;
}
运行的时候会报错,要把int operator[](char *cp) 改成int operator[](const char *cp)