-4
 int main()
 {
     CComplex c1(9,9);
     CComplex c3;
     c3 = 5 + c1;    // getting error here
     c3.print();
     cout << c3;

     return 0;
  }

  CComplex CComplex::operator+(const CComplex &complex)
  {
        CComplex temp;
        temp.m_real = complex.m_real + m_real;
        temp.m_imaginary = complex.m_imaginary + m_imaginary;
        return temp;
  }
Swordfish
  • 12,971
  • 3
  • 21
  • 43
yajnas
  • 1
  • Not sure if this is a dupe: [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) (None of the answers seem to tackle the problem why you need 2 operator overloads) – Yksisarvinen Nov 15 '18 at 08:46
  • You need to overload the + operator for int and not complex. Like this: `operator+(int c)` – itsundefined Nov 15 '18 at 08:49
  • For future reference, please state and explain what the problem, what you have attempted, and attach the error in full to the question. – TrebledJ Nov 15 '18 at 08:54
  • @itsundefined A non-member overload `operator+(int, CComplex)` is required here. – Yksisarvinen Nov 15 '18 at 09:01
  • His question is not clear whether or not he wants to support both – itsundefined Nov 15 '18 at 09:02

2 Answers2

0

You need overload + operator for int type and add some constructors if they are not defined

class CComplex
{
public:
    CComplex()
        : m_real(0), m_imaginary(0)
    { }
    CComplex(double real)
        : m_real(real), m_imaginary(0)
    { }
    CComplex(double real, double imaginary)
        : m_real(real), m_imaginary(imaginary)
    { }

    CComplex operator + (const CComplex& complex)
    {
        CComplex temp;
        temp.m_real = complex.m_real + m_real;
        temp.m_imaginary = complex.m_imaginary + m_imaginary;
        return temp;
    }

    double m_real;
    double m_imaginary;
};


CComplex operator + (const int value, const CComplex& complex)
{
    return CComplex(value) + complex;
}

std::ostream& operator << (std::ostream& os, const CComplex& complex)
{
    os << "(" << complex.m_real << "," << complex.m_imaginary << ")";
    return os;
}


int main()
{
    CComplex c1(9,9);
    CComplex c3;
    c3 = 5 + c1;    // no more error here
    std::cout << c3;
    return 0;
}

Result

(14,9)
serge
  • 992
  • 5
  • 8
  • Thank you for your quick response @serge . why can't we define the function inside the class. As there will be two overloaded function for the same operator. – yajnas Nov 15 '18 at 11:59
  • Yes, we can :) The method should be marked as `friend` for integer type overloading. – serge Nov 15 '18 at 12:43
  • The function does not need to be marked as `friend`. It only uses the public interface. In order to define that function inside the class it has to be `static`; otherwise it would expect a `CComplex` as its left-hand argument. – Pete Becker Nov 15 '18 at 14:47
  • @PeteBecker try to compile it as non-friend or static https://wandbox.org/permlink/xK6mASKu8XO2IvzP – serge Nov 15 '18 at 15:09
  • Again, perhaps more clearly: `friend` would give it access to private members. That function does not use any private members. There is a possible issue with defining different versions of an overloaded in different scopes, but `friend` is not the appropriate answer. – Pete Becker Nov 15 '18 at 17:08
  • @PeteBecker again, did you try to compile the example? The `<<` operator has access to private members. The `+` one potentially should have access, too. Take a look also at [Microsoft's example](https://learn.microsoft.com/en-us/cpp/standard-library/overloading-the-output-operator-for-your-own-classes) which uses `friend` and explain why Microsoft guys answer is "not appropriate". – serge Nov 16 '18 at 09:02
  • What private members? Everything in your code example is public. Regardless, the fact that you wrote a `<<` that wouldn't work if you wrote some other code differently doesn't change the fact that the `operator+` under discussion doesn't uses only obviously public interface functions. – Pete Becker Nov 16 '18 at 15:21
  • @PeteBecker did you try to compile your suggestion at least? Could you explain why Microsoft's example is not appropriate? – serge Nov 16 '18 at 15:24
  • Please stop. I didn't **suggest** anything. I haven't looked at Microsoft's example, and I have no intention of doing so. I made a simple statement about the code you presented. Nothing more. I stand by that statement: that `operator+` does not need to be a friend. It uses only public interface functions. – Pete Becker Nov 16 '18 at 15:26
  • @PeteBecker yes you do. 1/ _In order to define that function inside the class it has to be static_ 2/ try to compile the code without `friend` and/or with `static`. Please don't make suggestions that cannot be even compiled. – serge Nov 16 '18 at 15:46
0

I think the correct solution is:

class CComplex {
public:
  CComplex();
  CComplex(int);  // NEW - CONVERSION CONSTRUCTOR
  CComplex(double real);
  CComplex(double real, double imaginary);
  friend CComplex operator + (const CComplex& a, const CComplex& b); // FRIEND - NON-MEMBER FUNCTION
};

Please note these features in the code:

  • There is a constructor getting one int parameter. This is a casting constructor that the compiler can use for automatic conversion from an int to CComplex.
  • operator+ is a non-member function (friend keyword makes the function non-member). It slightly differs from the situation when operator+ is a member function (CComplex operator+(CComplex const &b) const).

If you write:

CComplex c1;
5 + c1;

Then for 5 + c1 there is searched an operator+ with parameters (int,CComplex). According to C++ standard there is allowed only one conversion to get proper parameter types (sorry I have no formal quotation). There is a conversion constructor from int to CComplex so there is automatically called this conversion constructor and then operator+(CComplex,CComplex) with proper parameters.

If you didn't have CComplex(int) constructor, then 5 + c1 would not work because there are needed TWO conversion from: int to double and from double to CComplex.

Additionaly, if operator+ was a member function (not friend), it wouldn't work at all. Because according C++ standard there is no possibility of automatic conversion for the left operand. So even conversion constructor CComplex(int) wouldn't help.

Plus: I think that overloading operator+ for types like (int, CComplex) is not a good idea because it would cause explosion of declarations. The same you would need for operator-() and for any order of operands - e.g. (CComplex,int), (CComplex,long), etc... By providing conversion constructor from required types you get all these combinations "automatically" and "for free".

Jarek C
  • 1,077
  • 6
  • 18