我试图理解运营商超载的想法,我已经达到了这一点,当它全部聚集在一起时,我可能会得到它的支持,但...... < / 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的定义,它的外观,它存储了哪些信息?
谢谢!
答案 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+()
与first
和second
。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
时,您不会同时修改a
或b
。虽然这听起来很奇怪,但它仍然是原样。对于流,这是由于流被修改(即使您只将指针移动到流中的当前位置)。至于复数,这是由于任务的完成。
此情况下的返回类型必须为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();` `
}