运算符重载如何工作,为什么在我的情况下不起作用?
How does operator overloading work, and why doesn't it work in my case?
我得到了一个驱动程序功能,该功能应该证明涉及复数的运算符超载的结果。在阅读过多的一段时间后,我设法以成功编译的方式编写代码,但是在此过程中,程序未输出正确的值。
据我了解,超载基本上像功能一样工作。将对象传递,然后"函数"可以进行算术/对其进行任何操作并返回新对象。不过,我有点迷路的地方是如何超负荷知道要传递的值。例如,在我的情况下,我将" "answers" ="运算符重载,以便在" x = y z"的形式中添加两个复数。当编译器遇到" ="符号时,我假设它只是通过左侧和右侧的任何内容并通过这些符号?与" "相同。在这种情况下,它将传递" y",因为它是左侧的对象和" z",因为它是右侧的对象?
这是我当前的"复杂"类,其中包括过载定义。
class Complex {
private:
double realPart;
double imaginaryPart;
public:
// friends
friend ostream & operator<<(ostream &out, const Complex &c);
friend istream & operator>>(istream &in, Complex &c);
// constructors
Complex()
{
realPart = 0;
imaginaryPart = 0;
}
Complex(double real)
{
realPart = real;
imaginaryPart = 0;
}
Complex(double real, double imaginary)
{
realPart = real;
imaginaryPart = imaginary;
}
// end of constructors
// + overloading
Complex operator+(Complex const &c)
{
Complex Add;
Add.realPart = realPart + c.realPart;
Add.imaginaryPart = imaginaryPart + c.imaginaryPart;
return Add;
}
// - overloading
Complex operator-(Complex const &c)
{
Complex Subtract;
Subtract.realPart = realPart - c.realPart;
Subtract.imaginaryPart = imaginaryPart - c.imaginaryPart;
return Subtract;
}
// * overloading
Complex operator*(Complex const &c)
{
Complex Multiply;
Multiply.realPart = (realPart * c.realPart) - (imaginaryPart * c.imaginaryPart);
Multiply.imaginaryPart = (realPart * c.imaginaryPart) - (imaginaryPart * c.realPart);
return Multiply;
}
// = overloading
Complex operator=(Complex const &c)
{
Complex Assignment;
Assignment.realPart = realPart;
Assignment.imaginaryPart = imaginaryPart;
return Assignment;
}
// == overloading
bool operator==(Complex const &c)
{
Complex Compare;
if (Compare.realPart == realPart && Compare.imaginaryPart == imaginaryPart)
{
return true;
}
else
{
return false;
}
}
// != overloading
bool operator!=(Complex const &c)
{
Complex NotEqual;
if (NotEqual.realPart == realPart && NotEqual.imaginaryPart == imaginaryPart)
{
return false;
}
else
{
return true;
}
}
};
// << overloading
ostream& operator<<(ostream& out, const Complex &c)
{
out << c.realPart;
if (c.imaginaryPart >= 0)
{
out << " + " << c.imaginaryPart << "i" << endl;
}
else
{
out << " - " << fabs (c.imaginaryPart) << "i" << endl;
}
return out;
}
// >> overloading
istream& operator>>(istream &in, Complex &c)
{
in >> c.realPart;
in >> c.imaginaryPart;
return in;
}
这是驱动程序程序:
int main()
{
for (double i = 1; i < 10; ++ i)
{
Complex y{i * 2.7, i + 3.2};
Complex z{i * 6, i + 8.3};
Complex x;
Complex k;
std::cout << "Enter a complex number in the form: (a, b)n? ";
std::cin >> k; // demonstrating overloaded >>
std::cout << "x: " << x << "ny: " << y << "nz: " << z << "nk: " << k << 'n'; // demonstrating overloaded <<
x = y + z; // demonstrating overloaded + and =
std::cout << "nx = y + z:n" << x << " = " << y << " + " << z << 'n';
x = y - z; // demonstrating overloaded - and =
std::cout << "nx = y - z:n" << x << " = " << y << " - " << z << 'n';
x = y * z; // demonstrating overloaded * and =
std::cout << "nx = y * z:n" << x << " = " << y << " * " << z << "nn";
if (x != k)
{ // demonstrating overloaded !=
std::cout << x << " != " << k << 'n';
}
std::cout << 'n';
x = k;
if (x == k)
{
// demonstrating overloaded ==
std::cout << x << " == " << k << 'n';
}
std::cout << std::endl;
}
}
运行后,问题似乎与对象" x"有关。输入" 5 2"仍将输出" x:0 0i",这使我相信问题是" ="的重载或流动机。也就是说,我无法弄清楚为什么什么都没发生。
我认为我如何构造" ="过载定义有错误,还是我缺少更大的东西?
您的=
是错误的;它应该返回*this
。
Complex& operator=(Complex const &c)
{
realPart = c.realPart;
imaginaryPart = c.imaginaryPart;
return *this;
}
修复了这一点,其余的大部分看起来很理智。
operator=()
不正确:用户Yakk - Adam
已经向您展示了如何修复它。让您了解为什么它是错误的以及return *this
做什么;让我们看一下您的原始功能:
Complex operator=(Complex const &c) { Complex Assignment; Assignment.realPart = realPart; Assignment.imaginaryPart = imaginaryPart; return Assignment; }
在这里,您的签名将const引用到另一个 Complex
对象,此部分是正确的。您的返回类型是Complex
对象,这本质上是错误的,因为您不想返回对象的副本。这里的目的是执行作业。这意味着您必须更改原始LHS
实例。
在表达式A = B + C
中;A
被视为LHS
实例。在这里,您需要分配两个RHS
值的表达式(B + C)
。
因此,当Yakk - Adam
向您展示如何解决此问题时:
Complex& operator=(Complex const &c) { realPart = c.realPart; imaginaryPart = c.imaginaryPart; return *this; }
这里的区别之一是,返回类型现在是特定对象的 Reference
,而不是对象的副本。
另一个区别是,不需要像您在原始版本中那样创建本地临时副本:
Complex Assignment; // this is not needed
通过从operator=()
中删除他只是替换了这些代码:
// Assignment.realPart = realPart; // To realPart = c.realPart; // Assignment.imaginaryPart = imaginaryPart; // To imaginaryPart = c.imaginaryPart;
在这里,您直接使用班级成员,并将属于另一个传递给操作员的c
的值分配。
然后最后返回带有更新值的LHS
实例;这是您必须返回此指针的地方。
*this
是什么意思?该指针是属于所有class
和struct
类型的特殊指针。例如,任何时候都有类对象:
class Foo {
public:
int bar { 10 };
void addFive();
};
您可以直接在成员功能中使用此指针:
void Foo::addFive() {
this->bar += 5; // same as below (this) belongs to this particular instance.
// bar += 5;
}
关于您的operator=()
;由于您是由reference
返回的,因此您不能仅仅是return this
。这将返回this
指针。我们不希望指向对象的指针,因为我们需要对对象进行引用。因此,我们必须通过返回*this
来尊重this
指针。
我希望这有助于为您清除一切。
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 为什么我的代码在输出中增加了93天
- 为什么我的for循环不能正确获取argv
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 为什么我的 std::ref 无法按预期工作?
- 为什么我的删除节点函数实际上没有删除节点?
- 为什么我的 IExtractIcon 处理程序没有被调用?
- 为什么我的多线程作业队列崩溃
- 为什么我的排序算法会更改数组值
- 为什么我的变量没有更新,我的 LED 没有亮起?
- 为什么我的程序在for循环中k=0时返回垃圾值
- 为什么我的点没有在 OpenGL 中绘制鼠标所在的位置?
- 为什么我的共享库中存在展开符号
- 为什么我的C++代码中出现'Segmentation Fault: 11'行?
- 为什么我的递归函数按降序打印,然后按升序打印?
- 为什么我的 heap.h 文件给我一个LNK2001错误?
- 为什么我的好友类无法访问私人会员?
- 为什么我的C++程序的程序集输出充满了 .ascii,没有汇编代码?
- 为什么我的模板化函数需要从一个迭代器转换到另一个迭代器?