运算符重载复数 - 附加功能
Operator overloading complex numbers - additional function
我试图理解运算符重载的想法,当它们全部组合在一起时,我可能会掌握它的窍门,但是......
我正在努力理解一些使用 + 运算符的代码,该代码已被重载,因此它将添加复杂的数字,代码非常简单。
#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);
重载添加运算符应该返回一些值,因为已经澄清它应该是复杂类型的值。
这样它看起来像在复杂类中声明,但它与构造函数有关吗?
我的意思是编译器现在会如何,"复杂"类型是什么样子的,因为它是一个类的名称,它与类的构造函数有关吗?
构造函数是否定义了类类型的值?
例如,我们有班级冷狗。
将一个名为 dog 的类类型的值如下所示:
狗的价值
狗类中的构造函数是否定义了值的定义,它的外观,它存储了哪些信息?
- 如何重载 ostream 运算符>> (cin( 以便用户可以指定自己的复数值?
谢谢!
注释
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( 创建一个临时的复杂对象(调用构造函数进行初始化(,按值返回将创建另一个临时对象以在调用者中使用。
过载>>声明为
friend istream& operator >> (istream&, complex&);
并定义为:
istream& operator >> (istream& i, complex& c) {
i >> c.Re >> c.Im;
return i;
}
运算符重载与构造函数无关(既不是默认的构造函数,也不是复制或移动构造函数;结果可能会被复制,具体取决于签名(。
你基本上告诉计算机如何将一些特定的运算符/操作应用于类的对象(或与其他值的任意组合,具体取决于可用的参数(。
那么它是如何工作的呢?
很简单。假设编译器找到如下结构:
result = first + second;
在这个例子中,我们有两个运算符,所以基本上有两个步骤:
-
operator+()
与first
和second
. -
operator=()
(赋值运算符(如果已定义(或复制构造函数(来分配result
。
因此,编译器知道它需要根据first
和second
的类型找到匹配operator+()
签名。基本上有两种基本方法可以定义它:
- 要么作为
first
班级的一员:... FirstClass::operator+(const SecondClass &secondObject)
(我的首选方式( - 或者作为具有两个参数的独立函数:
... operator+(const FirstClass &firstObject, const SecondClass &secondObject)
(对于无法更新的类,例如驻留在标准库(std
命名空间(中的类,这是执行此操作的唯一方法(。
我省略了返回类型,因为这些类型实际上取决于您。尽管不建议这样做,但您几乎可以返回任何内容,例如,您甚至不必使用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);
其他运算符也是如此,如>>
、||
、&
等。
#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();` `
}
- 重载算子新功能的限制
- 隐藏重载虚拟功能的模板化访客:SFINAE 在使用?
- 预处理器是否可以更改运算符重载功能的符号?
- 对象内部对象的重载功能
- 重载模板功能
- 谷歌测试的重载功能
- & 字符在重载 std::cout 中的功能是什么?
- 如何通过运算符<<的重载访问受保护的功能?C++
- 算子一元重载功能
- 模板模板功能的重载
- 具有自动功能的模板函数的重载分辨率
- 将重载函数分配给功能指针作为默认值
- 为什么BOOST.RANGE RANGE_BEGIN/END FREE功能对const和非const引用都重载
- 如何重载iostream运算符以在整个流上执行功能
- 优先级队列中的运算符重载或比较功能C++
- 在C++中,重载运算符后,运算符是否会失去其旧功能
- 如何使用此独特的操作员重载功能
- C++ <<运算符重载,无友元功能
- 可以通过常量说明符重载功能
- 赋值运算符重载/检索功能