采用面向对象程序设计方法实现对标准类型数据和复数类型数据进行加、减、乘、除、平方和立方(包括流插入运算符和流提取运算)运算的计算器
时间: 2023-12-26 16:04:38 浏览: 27
下面是一个可能的实现:
```c++
#include <iostream>
#include <cmath>
using namespace std;
class Calculator {
public:
Calculator() {}
~Calculator() {}
// 加法
template <typename T>
T add(T a, T b) {
return a + b;
}
// 减法
template <typename T>
T sub(T a, T b) {
return a - b;
}
// 乘法
template <typename T>
T mul(T a, T b) {
return a * b;
}
// 除法
template <typename T>
T div(T a, T b) {
return a / b;
}
// 平方
template <typename T>
T square(T a) {
return a * a;
}
// 立方
template <typename T>
T cube(T a) {
return a * a * a;
}
// 流插入运算符
template <typename T>
friend ostream& operator<<(ostream& os, const T& obj) {
os << obj.toString();
return os;
}
// 流提取运算符
template <typename T>
friend istream& operator>>(istream& is, T& obj) {
string str;
is >> str;
obj.fromString(str);
return is;
}
};
class Complex {
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
~Complex() {}
// 获取实数部分
double getReal() const {
return real;
}
// 获取虚数部分
double getImag() const {
return imag;
}
// 赋值
void setValue(double r, double i) {
real = r;
imag = i;
}
// 转为字符串
string toString() const {
return to_string(real) + (imag >= 0 ? "+" : "-") + to_string(abs(imag)) + "i";
}
// 从字符串转换
void fromString(const string& str) {
int pos = str.find("+");
if (pos == string::npos) {
pos = str.find("-");
imag = -stod(str.substr(pos + 1, str.length() - pos - 2));
} else {
imag = stod(str.substr(pos + 1, str.length() - pos - 2));
}
real = stod(str.substr(0, pos));
}
// 加法
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
// 减法
Complex operator-(const Complex& other) const {
return Complex(real - other.real, imag - other.imag);
}
// 乘法
Complex operator*(const Complex& other) const {
return Complex(real * other.real - imag * other.imag, real * other.imag + imag * other.real);
}
// 除法
Complex operator/(const Complex& other) const {
double denominator = other.real * other.real + other.imag * other.imag;
return Complex((real * other.real + imag * other.imag) / denominator, (imag * other.real - real * other.imag) / denominator);
}
// 平方
Complex pow2() const {
return Complex(real * real - imag * imag, 2 * real * imag);
}
// 立方
Complex pow3() const {
return pow2() * Complex(real, imag);
}
private:
double real;
double imag;
};
int main() {
Calculator calc;
int a = 10, b = 3;
cout << "a + b = " << calc.add(a, b) << endl;
cout << "a - b = " << calc.sub(a, b) << endl;
cout << "a * b = " << calc.mul(a, b) << endl;
cout << "a / b = " << calc.div(a, b) << endl;
cout << "a^2 = " << calc.square(a) << endl;
cout << "a^3 = " << calc.cube(a) << endl;
Complex c1(1, 2), c2(3, 4);
cout << "c1 + c2 = " << calc.add(c1, c2) << endl;
cout << "c1 - c2 = " << calc.sub(c1, c2) << endl;
cout << "c1 * c2 = " << calc.mul(c1, c2) << endl;
cout << "c1 / c2 = " << calc.div(c1, c2) << endl;
cout << "c1^2 = " << calc.square(c1) << endl;
cout << "c1^3 = " << calc.cube(c1) << endl;
cout << "输入一个复数:";
Complex c;
cin >> c;
cout << "输入的复数为:" << c << endl;
return 0;
}
```
在这个实现中,我们定义了一个 `Calculator` 类,其中包含了标准类型数据和复数类型数据的加、减、乘、除、平方和立方运算。对于复数类型数据,我们使用了一个 `Complex` 类来表示复数,并在其中定义了各种运算。
在 `Calculator` 类中,我们使用了 C++ 的模板技术,使得我们可以使用相同的代码来处理不同类型的数据。具体来说,我们在各种运算方法中使用了 `template` 和 `typename` 关键字,来表示这些方法可以接受任意类型的参数。例如,`add` 方法的定义为:
```c++
template <typename T>
T add(T a, T b) {
return a + b;
}
```
这里的 `typename T` 表示我们接受一个任意类型的参数 `T`,并返回一个 `T` 类型的结果。
在 `Complex` 类中,我们定义了各种运算符重载方法,来实现复数的加、减、乘、除、平方和立方运算。其中,加、减、乘、除运算符的重载方法使用了常见的复数运算公式,而平方和立方运算则是直接调用了 `pow2` 和 `pow3` 方法。
最后,在 `Calculator` 类中,我们还重载了流插入运算符和流提取运算符,来实现将复数类型数据输入和输出到流中。这里我们使用了模板特化的方法,来实现对 `Complex` 类型的流插入和流提取。具体来说,我们在 `Calculator` 类中定义了如下两个友元函数:
```c++
template <typename T>
friend ostream& operator<<(ostream& os, const T& obj) {
os << obj.toString();
return os;
}
template <typename T>
friend istream& operator>>(istream& is, T& obj) {
string str;
is >> str;
obj.fromString(str);
return is;
}
```
其中,`ostream& operator<<` 表示流插入运算符,`istream& operator>>` 表示流提取运算符。这两个函数中,第一个参数表示输出或输入流,第二个参数表示要输出或输入的对象。我们通过调用 `toString` 和 `fromString` 方法,来将复数类型数据转换为字符串和从字符串中解析出复数类型数据。注意,我们在这里使用了 `obj.toString()` 和 `obj.fromString(str)`,而不是 `obj->toString()` 和 `obj->fromString(str)`,这是因为我们在这里传递的是对象本身,而不是指向对象的指针。