用类方法求解一元二次实系数方程

来源:互联网 发布:java引用dll文件 编辑:程序博客网 时间:2024/03/28 20:05
用类方法求解一元二次方程
实现一个Complex类和一个Real类.将Real类定义为Complex类的子类.然后设计一个求解一元二次实系数方程的根的类Root.
class Root
{
public:
const Complex & Solve();
...
};
注意:上面对成员函数Root::Solve的声明只是示意性的.可以根据设计进行变通.

#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;

class Complex {
public:
Complex(double r = 0, double i = 0) : real_(r), imag_(i) {}
Complex& operator=(const Complex& a){
if(this == &a) return *this ;
this->real_=a.real();
this->imag_=a.imag();
return *this;
}
Complex& operator=(double a){
real_=a;
imag_=0.0;
return *this;
}
double real() const { return real_;}
double imag() const { return imag_;}

protected:
double real_, imag_;
};
inline bool operator==(Complex a, Complex b) {
return a.real() == b.real() && a.imag() == b.imag();
}

inline bool operator!=(Complex a, Complex b) {
return !(a==b);
}

inline Complex operator+(Complex a, Complex b) {
return Complex(a.real() + b.real(), a.imag() + b.imag());
}

inline Complex operator-(Complex a, Complex b) {
return Complex(a.real() - b.real(), a.imag() - b.imag());
}

inline Complex operator*(Complex a, Complex b) {
return Complex(a.real() * b.real() - a.imag() * b.imag(),
a.real() * b.imag() + a.imag() * b.real());
}

inline Complex operator/(Complex a, Complex b) {
if (b == Complex(0.0, 0.0)) {
cerr << "devide by zero" << endl;
exit(1);
}
double d = b.real() * b.real() + b.imag() * b.imag();
return Complex((a.real() * b.real() - a.imag() * b.imag()) / d,
(a.imag() * b.real() + a.real() * b.imag()) / d);
}

inline ostream& operator<<(ostream& out, const Complex& c) {
return out << "(" << c.real() << "+" << c.imag() << "i)";
}

class Real : public Complex {
public:
explicit Real (double r = 0) : Complex(r) {}

friend istream& operator>>(istream& in, Real& r) {
return in >> r.real_;
}
};

inline Real operator+(Real a, Real b) {
return Real(a.real() + b.real());
}

inline Real operator-(Real a, Real b) {
return Real(a.real() - b.real());
}
inline Real operator-(Real a) {
return Real(-a.real());
}

inline Real operator*(Real a, Real b) {
return Real(a.real() * b.real());
}
inline Real operator*(int a, Real b) {
return Real(a * b.real());
}

inline Real operator/(Real a, Real b) {
if (b.real() == 0.0) {
cerr << "divide by zero" << endl;
exit(1);
}
return Real(a.real()/b.real());
}

inline Complex operator+(Real a, Complex b) {
return Complex(a.real() + b.real(), 0.0 + b.imag());
}

inline Complex operator-(Real a, Complex b) {
return Complex(a.real() - b.real(), 0.0 - b.imag());
}

inline ostream& operator<<(ostream& out, const Real& r) {
return out << r.real();
}

Complex sqrt_(Real r) {
return r.real() < 0.0 ? Complex(0.0, sqrt(r.real())) : Complex(sqrt(r.real()));
}

class Root {
public:
Root(Real a, Real b, Real c) : a_(a), b_(b), c_(c) {}

void Solve();

Complex operator[](int i) const { return result_[i]; }
private:
Real a_, b_, c_;
Complex result_[2];
};

inline ostream& operator<<(ostream& out, const Root& r) {
return out << "[ " << r[0] << ", " << r[1] << " ]";
}

void Root::Solve() {
Complex delta = sqrt_(b_ * b_ - 4 * a_ * c_);//为什么这里说不能编译通过?? (1)
result_[0] = (- b_ + delta) / Complex(2);//这里该怎么重载父类和子类的“+,-” (2)
result_[1] = (- b_ - delta) / Complex(2);(5)
}

int main() {
Real a, b, c;
cin >> a >> b >> c;
Root root(a, b, c);
root.Solve();
cout << root;
system("pause");
}/*
Complex operator=(const Complex& a){
if(this == &a) return *this ;//或者 if(this == &a) return a ;都可以 (3)
this->real_=a.real();
this->imag_=a.imag();
return *this;
}
Complex& operator=(const Complex& a){
if(this == &a) return *this ;//这里 if(this == &a) return a ;编译不通过 (4)
this->real_=a.real();
this->imag_=a.imag();
return *this;
}
*/
 (1)因为之前没有重载int*Real操作,所以报错;
 (2)重载一个函数 ,就可以使得父类和子类进行运算;
 (3)因为函数的返回值是一个值,所以不管是返回的*this或者常引用a都可以编译通过;
 (4)因为函数的返回值是一个引用,所以当return a;操作时会编译通不过,类型不匹配,
  当把函数的返回值改成常引用就可以了,但这样的操作觉得不怎么恰当,因为赋值操作
  的结果是一个可以递进操作的左值,所以返回值用引用较好,但不要是常引用;
 (5)表达式的值是一个常量来着,所以在执行 result_[1] = (- b_ - delta) / Complex(2);
   操作的时候,函数的形参必须是一个常量引用,即 Complex& operator=(const Complex& a)

  



原创粉丝点击