运算符重载是如何工作的,为什么它在我的情况下不起作用?

问题描述 投票:0回答:2

我已经提供了一个驱动程序函数,它应该演示涉及复数的运算符重载的结果。在读完一段时间后,我设法以成功编译的方式编写代码,但是在某些地方,程序没有输出正确的值。

根据我的理解,重载基本上就像一个函数。对象被传递,然后“函数”可以对它进行算术运算,并返回一个新对象。虽然我有点迷失,但重载是如何知道传递的值。例如,在我的情况下,我重载了“+”和“=”运算符,以便以“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 << "\n\n";

        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”这使我相信问题是“=”或流运算符的重载。也就是说,我无法弄清楚为什么没有发生任何事情。

在我如何构建“=”重载定义时是否存在错误,或者它可能是我想要的更大的东西?

c++ overloading operator-keyword
2个回答
3
投票

你的=错了;它应该返回*this

Complex& operator=(Complex const &c)
{
  realPart = c.realPart;
  imaginaryPart = c.imaginaryPart;
  return *this;
}

解决这个问题,其余大部分看起来都很清醒。


1
投票

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的例子。在这里,您要分配表达式(B + C),它们都是RHS值。

所以,当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是什么意思? this指针是一个特殊的指针,属于所有classstruct类型。例如,任何时候你有类对象:

class Foo {
public:
    int bar { 10 };

    void addFive();
}; 

您可以直接在成员函数中使用this指针:

void Foo::addFive() {
    this->bar += 5; // same as below  (this) belongs to this particular instance.
    // bar += 5;        
}

关于你的operator=();因为你回来的reference你不能简单地只是return this。这将返回this指针。我们不希望指向对象的指针,因为我们想要对对象的引用;所以我们必须通过返回this来尊重*this指针。

我希望这有助于为您解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.