0

I have overloaded postincrement (a++) operator in my code and I am attempting to overload the preincrement operator (++a) in my code to perform a function that squares the complex number "a", however, only the postincrement operator is working at the moment. I should make explicitly clear that both the pre and post increment operators call the same function -- they should both use the square method/function. So they should give me the same answer despite being in post/pre positions.

When called, the preincrement operator has a red line underneath it that says: "more than one operator ++ matches these operands. Yet I've explicitly delcared "++()" and "++(int)" to account for both ++a and a++.

Am I missing something? Here is my code.

#include<iostream>
#include<iomanip>
using namespace std;

class ComplexNum
{
public:
    ComplexNum(float = 0.0, float = 0.0); //default constructor that uses default arg. in case no init. are in main
    ComplexNum& getComplexNum(); //get real and imaginary numbers from keyboard
    ComplexNum& sum(ComplexNum a, ComplexNum b); //method to add two ComplexNum numbers together
    ComplexNum& diff(ComplexNum a, ComplexNum b); //method to find the difference of two complex numbers
    ComplexNum& prod(ComplexNum a, ComplexNum b); //method to find the product of two complex numbers
    ComplexNum& square(ComplexNum a); //method to find square using pre/post increment operators

    //overloaded operators
    ComplexNum& operator =  (const ComplexNum& that) = default;
    ComplexNum& operator += (const ComplexNum& that) { return sum(*this, that); }
    ComplexNum& operator -= (const ComplexNum& that) { return diff(*this, that); }
    ComplexNum& operator *= (const ComplexNum& that) { return prod(*this, that); }
    ComplexNum& operator ++() { return square(*this); } //called for ++num
    ComplexNum operator ++(int) { return square(*this); } //called for num++

    ostream& print(ostream& stm = cout) const;


private:
    float real; //float data member for real number (to be entered in by user)
    float imaginary; //float data member for imaginary number (to be entered in by user)

    //non-member overloaded operators
    //a is passed by value
    friend ComplexNum operator+ (ComplexNum a, const ComplexNum& b) { return a += b; }
    friend ComplexNum operator- (ComplexNum a, const ComplexNum& b) { return a -= b; }
    friend ComplexNum operator* (ComplexNum a, const ComplexNum& b) { return a *= b; }
    friend ComplexNum operator++(ComplexNum a) { return a++; } //friend for num ++
    friend ComplexNum operator++(ComplexNum a) { return ++a; } //friend for ++num

    friend ostream& operator<< (ostream& stm, const ComplexNum& c) { return c.print(stm); }
};

ComplexNum::ComplexNum(float a, float b)
{
    real = a;
    imaginary = b;
}

ComplexNum& ComplexNum::getComplexNum()
{
    ComplexNum keyboard;
    cout << "Enter real part of complex number: ";
    cin >> real;

    cout << "Enter imaginary part of complex number: ";
    cin >> imaginary;

    return keyboard; 
}

ComplexNum& ComplexNum::square(ComplexNum a)
{
    this->real = (a.real * a.real) - (a.imaginary * a.imaginary);
    this->imaginary = (2 * (a.real * a.imaginary));
    return *this;
}

ComplexNum& ComplexNum::sum(ComplexNum a, ComplexNum b)
{
    this->real = a.real + b.real;
    this->imaginary = a.imaginary + b.imaginary;
    return *this;
}

ComplexNum& ComplexNum::diff(ComplexNum a, ComplexNum b)
{
    this->real = a.real - b.real;
    this->imaginary = a.imaginary - b.imaginary;
    return *this;
}

ComplexNum& ComplexNum::prod(ComplexNum a, ComplexNum b)
{
    this->real = (a.real * b.real) - (a.imaginary * b.imaginary);
    this->imaginary = (a.real * b.imaginary) + (b.real * a.imaginary);
    return *this;
}

ostream& ComplexNum::print(ostream& stm) const
{
    return stm << "(" << noshowpos << real << showpos << imaginary << "i)";
}

int main()
{
    ComplexNum a, b;
    cout << "First Complex Number:" << endl;
    a.getComplexNum();
    cout << endl;
    cout << "Second Complex Number:" << endl;
    b.getComplexNum();
    cout << endl;
    cout << fixed << setprecision(2)
        << "a == " << a << '\n'
        << "b == " << b << '\n'
        << "a+b == " << a + b << '\n'
        << "a-b == " << a - b << '\n'
        << "a*b == " << a*b << '\n'
        << "a*a == " << a*a << '\n'
        << "b*b == " << b*b << '\n';
        cout << "a*a (using postincrement) == " << a++ << '\n'; //works fine
        cout << "a*a (using preincrement) == " << ++a << '\n'; //gives me a [more than one operator error] underneath "++" 
        cout << endl;

    system("PAUSE");
}
garyoak
  • 41
  • 3
  • Maybe because you have two preincrement operators? How is it supposed to know which one to call? – user253751 Feb 13 '17 at 01:31
  • 2
    Your "//friend for num ++" and "//friend for ++num" have the exact same signature. So one of them is lying. – tkausl Feb 13 '17 at 01:31
  • @tkausl, I was under the impression that different returns implicitly meant different signatures. I was wrong. Thank you for clarifying that. Does that mean I need to change the argument inside //friend for ++num? Thanks again. – garyoak Feb 13 '17 at 01:39
  • They have the same return type though. Check out [this list](https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B#cite_ref-alignof_10-0). – tkausl Feb 13 '17 at 01:40
  • I examined the list, and I seem to be following the protocol properly for post/pre inside a class. I tried changing the argument inside `++num` `friend` to be `operator++(ComplexNum&, a)` but it said that `a` was undefined and gave me more redlines. – garyoak Feb 13 '17 at 01:53
  • @immibis, where do you see two preincrement operators? I see one for ++num and one for num++...and both have their specific notation. – garyoak Feb 13 '17 at 01:55
  • @garyoak I see two that are friends (but I only counted one since I'm assuming that's a typo) and one that is a member. – user253751 Feb 13 '17 at 02:44

1 Answers1

0

Non-member preincrement signature is

T& operator++(T& a); // ++a

And non-member postincrement is

T operator++(T& a, int); // a++

You must change these definitions to

friend ComplexNum& operator++(ComplexNum& a, int) { return a++; } //friend for num ++
friend ComplexNum operator++(ComplexNum& a) { return ++a; } //friend for ++num
joas
  • 170
  • 1
  • 5
  • I fixed the friend notation inside my class per your advice. However, I am now getting errors underneath the `++a` and `a++` inside the main, saying again that `more than one operator "++" matches these operands`. However, the red lines underneath the `friend` and `overload` have been resolved. – garyoak Feb 13 '17 at 02:04
  • More specifically, it gives me `C2593: 'operator ++' is ambiguous` – garyoak Feb 13 '17 at 02:11
  • So I changed `ComplexNum&a` inside both friends to `const ComplexNum& a` and it did the trick, but now I get a runtime error wherein it takes the complex number `a`, squares it, and then squares it again. When it should be giving me the same answer. Both `a++` and `++a` should be the same answer, that is. – garyoak Feb 13 '17 at 02:14
  • Oops..and so it is, sorry. Non-member operators are often used to operate with fundamental types or are already defined. You must delete one of the two modes. – joas Feb 13 '17 at 02:17
  • So I have to create two functions one for post increment and one for preincrement in order to get the same answer for both without them bleeding into one another? – garyoak Feb 13 '17 at 02:20
  • No, you just must remove the post and preincrement non-members overloaded operators. – joas Feb 13 '17 at 02:26
  • When I removed the post/preincremented non-member operators it still gave me a runtime error wherein `++a` is a square of a square whereas it should just be a square. Does that makes sense? I know my wording might be bad, so I apologize in advance. However, `a++` is fine. It gives me just a square. I think the value of `a` is being morphed so that when `++a` is used in the main, the compiler says: "Oh! You need `a`? Well, last we checked, `a` is the square of itself since we just ran `a++` so, here you go -- a square of a square........... – garyoak Feb 13 '17 at 02:32
  • You can use another less common operator, such as the `operator~` (one's complement), or `operator%` (modulo). – joas Feb 13 '17 at 02:45
  • I tried both `~` and `%` and neither of them worked. Thank you for staying with me here, @joas. – garyoak Feb 13 '17 at 02:48
  • I suspect it has something to do with the sequence of `cout` inside the main, because I had problems with this before, and it was an issue inside the main. I'm not sure what it might be...I may have to instantiate another ComplexNum? I don't know... – garyoak Feb 13 '17 at 02:56
  • All methods in your class create new instances because the parameters are not references or pointers. – joas Feb 14 '17 at 04:42