简体   繁体   中英

Unary Negation in C++

I am almost done with this program, but I am having trouble applying the unary negation function to it.

I have made a program based on calculating complex numbers and so far it works perfectly well, except for the whole negative numbers part. I can't seem to figure out how to make my unary negation to work in the code without it warning me and crashing on me with its runtime error.

In my h file, I have this:

Complex operator-(const Complex &lhs);

and in my cpp file, I attempted to create this from what I wrote above:

Complex operator-(const Complex &lhs)
{
    return Complex(-lhs);
}

The code I wrote on my cpp file gives me a Warning C4717 error that says: "'operator-': recursive on all control paths, function will cause runtime stack overflow." And of course, applying the number above would cause runtime error.

I'm sure some of you want the full code, so here it is: header, cpp, and the test file. :)

I appreciate the help.

header file:

#ifndef com_H
#define com_H
#include <iostream>
#include <string>

using namespace std;


/********** CLASS **********/

class Complex
{

    //The BFFs: Stream Insertion and Operators//

    friend istream &operator >> (istream &lhs, Complex &rhs);
    friend ostream &operator << (ostream &lhs, const Complex &rhs);

private:

    float real, img;

public:
            //Complex Constructor//

    Complex(float new_real = 0.0, float new_img = 0.0);

            //Complex Set-and-Get Functions//

    void setComplex(float new_real, float new_img);
    float getReal() const { return real; }
    float getImg()  const { return img; }

            //Complex Functions//

    Complex &operator+=(const Complex &rhs);
    Complex &operator-=(const Complex &rhs);
    Complex &operator*=(const Complex &rhs);
    Complex &operator/=(const Complex &rhs);

};


/********** O P E R A T O R **********/



Complex operator+(const Complex &lhs, const Complex &rhs);
Complex operator-(const Complex &lhs, const Complex &rhs);
Complex operator*(const Complex &lhs, const Complex &rhs);
Complex operator/(const Complex &lhs, const Complex &rhs);

//COMPARISON OPERATORS*/

bool operator==(const Complex &lhs, const Complex &rhs);
bool operator!=(const Complex &lhs, const Complex &rhs);
bool operator<(const Complex &lhs, const Complex &rhs);
bool operator<=(const Complex &lhs, const Complex &rhs);
bool operator>(const Complex &lhs, const Complex &rhs);
bool operator>=(const Complex &lhs, const Complex &rhs);

//NEGATION//
Complex operator-(const Complex &lhs);

#endif

cpp file:

#include <iostream>
#include <string>
#include <stdlib.h>
#include <math.h>
#include "com.h"

using namespace std;

//
//***************** COMPLEX CONSTRUCTORS *****************//
//
Complex::Complex(float new_real, float new_img)
{
    real = new_real;
    img = new_img;
}

void Complex::setComplex(float new_real, float new_img)
{
    real = new_real;
    img = new_img;
}


//
//***************IF REAL NUMBER IS ZERO CHECK***************//
//

void checkNum(char ops, float new_img)
{
    char i = 'i';

    if (new_img == 0)
    {
        cout << "0";
    }

    else if (new_img != 1 && ops == '-')
    {
        new_img *= -1;

        cout << new_img << i;
    }

    else if (new_img == 1 && ops == '-')
    {
        cout << "-i";
    }

    else if (new_img == 1)
    {
        cout << i;
    }

    else
    {
        cout << new_img << i;
    }

}

//
//*****************STREAM INSERTIONS*****************//
//

istream &operator >> (istream &lhs, Complex &rhs)
{
    char ops;
    char i = 'i';

    lhs >> rhs.real >> ops >> rhs.img >> i;     //lhs is another name for cin

    if (ops == '-')
    {
        rhs.img *= -1;
    }

    return lhs;
}

ostream &operator << (ostream &lhs, const Complex &rhs)
{
    char ops;
    char i = 'i';
    float new_real = rhs.real;
    float new_img = rhs.img;

    if (new_img < 0)
    {
        ops = '-';
        new_img *= -1;
    }

    else if (new_img >= 0)
    {
        ops = '+';
    }

    if (new_real == 0)
    {

        checkNum(ops, new_img);

        return  lhs << endl;

    }

    else if (new_img == 0)
    {
        return lhs << new_real;
    }

    else if (new_img == 1)
    {
        return lhs << new_real << " " << ops << " " << i;
    }

    else
    {
        return lhs << new_real << " " << ops << " " << new_img << i;
    }

    //  lhs << rhs.real << " + " << rhs.img << 'i';

}

//
//***************COMPLEX ARITHMETIC OPERATORS***************//
//***************** ( + | - | * | / |) ***************** //
//

// FORMULA for COMPLEX NUMBERS :: (a + bi)

Complex operator+(const Complex &lhs, const Complex &rhs)
{

    float a = lhs.getReal();
    float b = lhs.getImg();

    float c = rhs.getReal();
    float d = rhs.getImg();

    return Complex(a + c, b + d);

}

Complex operator-(const Complex &lhs, const Complex &rhs)
{

    float a = lhs.getReal();
    float b = lhs.getImg();

    float c = rhs.getReal();
    float d = rhs.getImg();

    return Complex(a - c, b - d);

}


Complex operator*(const Complex &lhs, const Complex &rhs)
{

    float a = lhs.getReal();
    float b = lhs.getImg();

    float c = rhs.getReal();
    float d = rhs.getImg();

    return Complex(((a * c) - (b * d)) , ((a * d) + (b * c)));


}

Complex operator/(const Complex &lhs, const Complex &rhs)
{

    float a = lhs.getReal();
    float b = lhs.getImg();

    float c = rhs.getReal();
    float d = rhs.getImg();

    //Numerator
    float myReal = (a * c) + (b * d);
    float myImg = (b * c) - (a * d);

    //Denominator
    float myDenom = (pow(c, 2) + pow(d, 2));

    return Complex(myReal / myDenom, myImg / myDenom);

}

//
//*****************COMPLEX OPERATORS EQUALS *****************//
//**************** ( += | -=  | *= | /= |) ***************** //
//

Complex &Complex::operator+=(const Complex &rhs)
{
    real += rhs.real;
    img += rhs.img;

    //*this = *this + rhs;

    return *this;
}

Complex &Complex::operator-=(const Complex &rhs)
{
    real -= rhs.real;
    img -= rhs.img;

    return *this;
}

Complex &Complex::operator*=(const Complex &rhs)
{
    real *= rhs.real;
    img *= rhs.img;

    return *this;
}

Complex &Complex::operator/=(const Complex &rhs)
{
    real /= rhs.real;
    img /= rhs.img;

    return *this;
}


//
//******************COMPLEX OPERATORS COMPARISON*****************//
//**************** ( == | != | < | <= | > | >= |)*****************//
//

bool operator==(const Complex &lhs, const Complex &rhs)
{
    if (lhs.getReal() == rhs.getReal() && lhs.getImg() == rhs.getImg())
    {
        return true;
    }

    return false;
}

bool operator!=(const Complex &lhs, const Complex &rhs)
{
    return !(lhs == rhs);
}

bool operator<(const Complex &lhs, const Complex &rhs)
{
    if (lhs.getReal() <  rhs.getReal() || lhs.getReal() == rhs.getReal() && lhs.getImg() < rhs.getImg())
    {
        return true;
    }
    return false;
}

bool operator<=(const Complex &lhs, const Complex &rhs)
{
    return ((lhs < rhs) || (lhs == rhs));
}

bool operator>(const Complex &lhs, const Complex &rhs)
{
    return !(lhs <= rhs);
}

bool operator>=(const Complex &lhs, const Complex &rhs)
{
    return !(lhs < rhs);
}

Complex operator-(const Complex &lhs)
{
    return Complex(-lhs);
}

main file:

#include <iostream>
#include "com.h"
#include <string>

using namespace std;

int  main()
{
    Complex  userValue;

    cout << "Enter a complex value (a + bi): ";

    cin >> userValue;

    cout << "Negated: " << -userValue << endl;

    cout << "Addition:  " << userValue + Complex(0.0, 0.0) << endl;

    if (Complex(-6, 5.2f) == userValue)
        cout << "Wow! It's equal." << endl;

    return  0;

}

UPDATE 1: Wow! I just tested it again and it actually crashes on any number I put, positive AND negative lol! But when I comment the following codes out... from main

//  cout << "Negated: " << -userValue << endl;

from header file

Complex operator-(const Complex &lhs); 

from cpp file

Complex operator-(const Complex &lhs)
{
    return Complex(-lhs);
}

...it still works (without the negative numbers of course.)

Like the error says, you're calling your overloaded function recursively. Instead you want to be calling the constructor with the proper arguments:

Complex operator-(const Complex &lhs)
{
    return Complex(-lhs.real, -lhs.imag);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM