-1

To overload operator +, I first implement that as friend function + normal function

class Cents
{
private:
  int m_cents;

public:
  Cents(int);
  int getCents() const;
  friend Cents operator+(const Cents&, const Cents&);
};

Cents::Cents(int cents)
  : m_cents{cents}
{}

int Cents::getCents() const
{
  return m_cents;
}

Cents operator+(const Cents &c1, const Cents &c)
{
  return Cents(c1.getCents() + c.getCents());
}

Cents operator+(const Cents &c, int v)
{
  return Cents(c.getCents()+v);
}

Cents operator+(int v, const Cents &c)
{
  return Cents(v+c.getCents());
}

int main()
{

  Cents c1{1};
  Cents c2{2};
  Cents c{c1+c2};
  Cents c3{c+3};
  Cents c4{4+c3};
  std::cout << c.getCents() << '\n';
  std::cout << c3.getCents() << '\n';
  std::cout << c4.getCents() << '\n';
  return 0;

}
>>>
3
6
10

It works well. But when I use a member function to replace the friend function, error raises

class Cents
{
private:
  int m_cents;

public:
  Cents(int);
  int getCents() const;
  Cents operator+(const Cents&);
};

Cents::Cents(int cents)
  : m_cents{cents}
{}

int Cents::getCents() const
{
  return m_cents;
}

Cents Cents::operator+(const Cents &c)
{
  return Cents(m_cents + c.getCents());
}

Cents operator+(const Cents& c, int v)
{
  return Cents(c.getCents()+v);
}

Cents operator+(int v, const Cents& c)
{
  return Cents(v+c.getCents());
}

int main()
{

  Cents c1{1};
  Cents c2{2};
  Cents c{c1+c2};
  Cents c3{c+3};
  Cents c4{4+c3};
  std::cout << c.getCents() << '\n';
  std::cout << c3.getCents() << '\n';
  std::cout << c4.getCents() << '\n';
  return 0;

}
>>>
error: invalid operands to binary expression ('int' and 'Cents')
  Cents c4{4+c3};

If Cents c4{4+c3}; and std::cout << c4.getCents() << '\n'; are removed, the rest code works fine

int main()
{
  Cents c1{1};
  Cents c2{2};
  Cents c{c1+c2};
  Cents c3{c+3};
//  Cents c4{4+c3};
  std::cout << c.getCents() << '\n';
  std::cout << c3.getCents() << '\n';
//  std::cout << c4.getCents() << '\n';
  return 0;
}
>>>
3
6

I guess it's because the compiler tries to resolve 4+c3 with the member function Cents operator+(const Cents&); and it can't use an int to call that function. But why can't the compiler use the normal function Cents operator+(int v, const Cents &c) to resolve 4+c3 as it did for Cents c3{c+3}; using Cents operator+(const Cents &c, int v)?

--- update ---

I am using Clion on macOS, but when I use an online compiler https://www.onlinegdb.com/online_c++_compiler the code (member function + normal function) compilers and runs successfully. But the online compiler also raises a warning


About • FAQ • Blog • Terms of Use • Contact Us • GDB Tutorial • Credits • Privacy
© 2016 - 2021 GDB Online
Language

    main.cpp

    input

main.cpp:54:14: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:                   
main.cpp:38:7: note: candidate 1: Cents operator+(const Cents&, int)                                                                                                                 
main.cpp:33:7: note: candidate 2: Cents Cents::operator+(const Cents&)                                                                                                               
3                                                                                                                                                                                    
6                                                                                                                                                                                    
10   

My follow-up question, since the friend function and normal function doesn't need a specific object to call the function, thus, they won't have parameters ordering issue. Does this make us prefer friend function or normal function over a member function when we are overloading an operator in C++?

Simon Z.
  • 598
  • 5
  • 11
  • Can you post the error you are getting? – Naseef Chowdhury Mar 17 '21 at 03:08
  • Most C++ gurus will tell you that a non-friend non-member version of the operator overload function is superior as it improves encapsulation. The function doesn't need to be a member to do its job, so it shouldn't. – Casey Mar 17 '21 at 03:23

1 Answers1

1

You dropped a const during the migration, should be Cents operator+(const Cents&) const.

Demo.

Jarod42
  • 203,559
  • 14
  • 181
  • 302