运算符重载复数 - 附加功能

时间:2014-09-24 07:00:35

标签: c++ operator-overloading

我试图理解运营商超载的想法,我已经达到了这一点,当它全部聚集在一起时,我可能会得到它的支持,但...... < / p>

我正在努力理解使用+运算符的一些代码,这些代码已被重载,因此它会添加复数,代码非常简单。

#include <iostream> 

using namespace std; 


class complex {
  protected:
  double Re, Im;

public:
  complex() : Re(0.0), Im(0.0) {} 
  complex(double Re, double Im) : Re(Re), Im(Im) {} 
  double getRe() const { return Re; }
  double getIm() const { return Im; }
  friend complex operator+(const complex&, const complex&); 
  friend ostream& operator<<(ostream&, const complex&); 
};

complex operator+(const complex& a, const complex& b) {
double r, i;
r = a.getRe() + b.getRe();
i = a.getIm() + b.getIm();
**return complex(r, i);** // *** CAN ANYONE EXPLAIN THIS BIT ? ***
}

ostream& operator<<(ostream& out, const complex &a) {
  out << "(" << a.getRe() << ", " << a.getIm() << ")" << endl;
  return out;
}

int main(void) {
  complex a(1,2), b(3,4), c;
  c = a+b;
  cout << c << endl;

}

我无法理解23行的确切含义:

return complex(r, i); 

重载的添加运算符应该返回一些值,因为它已被阐明它应该是复杂类型的值。

因此它看起来像在复杂的类中声明,但是它与构造函数有关吗?

我的意思是编译器现在如何,类型&#39;复杂&#39;看起来,因为它是一个类的名称,它是否与课程有关&#39;构造函数?

构造函数是否定义了类的类型?

例如,我们有班级冷狗。

一个名为dog的类的类型将是这样的:

狗的价值

dog类中的构造函数是否定义了value的定义,它的外观,它存储了哪些信息?

  1. 如何重载ostream运算符&gt;&gt; (cin)以便用户可以指定自己的复数值?
  2. 谢谢!

3 个答案:

答案 0 :(得分:0)

评论铭文

complex operator+(const complex& a, const complex& b) {
double r, i;
r = a.getRe() + b.getRe(); // real part of the result
i = a.getIm() + b.getIm(); // imaginary part of the result
return complex(r, i); // you are returning (by value) a complex number formed from r and i
}

这里,complex(r,i)创建一个临时复杂对象(调用构造函数进行初始化),并按值返回将创建另一个临时用于调用者。

重载&gt;&gt; 声明为

friend istream& operator >> (istream&, complex&);

并定义为:

istream& operator >> (istream& i, complex& c) {
  i >> c.Re >> c.Im;
  return i;
}

答案 1 :(得分:0)

运算符重载与构造函数无关(既不是默认的也不是复制或移动构造函数;结果可能会被复制,具体取决于签名)。

您基本上告诉计算机如何将某些特定的操作符/操作应用于您的类的对象(或根据可用的参数与其他值的任意组合)。

那它是如何运作的?

非常简单。让我们假设编译器找到一个这样的结构:

result = first + second;

在这个例子中,我们有两个操作符,基本上是两个步骤:

  • operator+()firstsecond
  • operator=()(赋值运算符(如果已定义)或复制构造函数)以分配result

因此,编译器知道需要根据operator+()first的类型找到匹配的second签名。基本上有两种基本方法可以定义:

  • 作为first班级的成员:... FirstClass::operator+(const SecondClass &secondObject)(我的首选方式)
  • 或作为具有两个参数的独立函数:... operator+(const FirstClass &firstObject, const SecondClass &secondObject)(对于无法更新的类执行此操作的唯一方法,例如驻留在标准库(std命名空间内)的类)。 / LI>

我省略了返回类型,因为这些取决于你。虽然不推荐,但你几乎可以返回任何东西,你甚至不必使用operator+()来“添加”。例如。

在具有复数的示例中,编译器将查找... complex::operator+(const complex &other)... operator+(const complex &left, const complex &right)或使用隐式转换可能使用的兼容运算符的任何变体。


对于涉及someInputStream >> myComplexNumber的问题的第二部分 - 如何实现缺少的运算符?

由于您没有直接访问权限来修改输入流类(无论它实际是什么),您必须在具有两个参数的类之外定义它。应用上面的知识变得非常简单:

std::istream &operator>>(std::istream &input, complex &number);

首先简要解释为什么参数中的引用不是const:你必须同时修改它们。这与典型的数学惯例相矛盾,例如在评估c = a + b时,您不会同时修改ab。虽然这听起来很奇怪,但它仍然是原样。对于流,这是由于流被修改(即使您只将指针移动到流中的当前位置)。至于复数,这是由于任务的完成。

此情况下的返回类型必须为istream &,因为您必须再次返回流对象。这是按惯例。从理论上讲(如上所述),您不必这样做,但通过这样做,您实现了预期的行为,允许用户链接这些运算符以读取多个内容,例如:像myStream >> complex1 >> complex2;这样的东西(这主要是评估为myStream >> complex1;myStream >> complex2)。

一旦你有了你的功能的签名,你只需填写内容,这也是一件容易的事情:

std::istream &operator>>(std::istream &input, complex &number) {
    input >> number.Re >> number.Im; // query the real and imaginary parts one after the other as doubles (since that's the members' type)
    return input; // return the stream again
}

如果您在理解这个(非常基本的)概念时遇到问题,请记住,运算符只是编写这些重载函数的便捷方式。您也可以使用+代替operator+(),而不是使用complexResult = complexNumber1 + complexNumber2; complexResult = operator+(complexNumber1, complexNumber2);

以下两行基本上是相同的:

>>

其他运营商也是如此,例如||&,{{1}}等。

答案 2 :(得分:0)

#include <iostream>
using namespace std;
class complex
{ private :
 int real ;
 int imag ;
 public :
complex(int real=0 , int imag=0)
{
    this->real=real;
    this->imag=imag;
}

complex operator +(complex ob2)
{  complex ob3;
    ob3.real=real + (ob2.real);
    ob3.imag=imag + (ob2.imag);
    return ob3; }
 void out()
{ cout<<real<<" + "<<imag<<"i"<<endl;}
};
int main()
{
int real_1,imag_1;
int real_2,imag_2;
cout<<"real part Enter    ";cin>>real_1;
cout<<"imaginary part Enter  ";cin>>imag_1;
complex ob(real_1,imag_1);
cout<<"real part Enter    ";cin>>real_2;
cout<<"imaginary part Enter  ";cin>>imag_2;
complex ob2(real_2,imag_2);
complex ans;
ans=ob+ob2;
    ans.out();`   `
}