2

I'm reading Effective C++ (Scott Meyers), and getting the error " no match for operator* " when trying to compile following code from this book:

rational.h

class rational
{
    private:
        int num;
        int den;
    public:
        rational(int n = 0, int d = 1);
        int getNum() const {return num;}
        int getDen() const {return den;}
};

rational.cpp

#include "rational.h"

rational::rational(int n,
                    int d)
    :num(n),
     den(d)
{}

const rational operator*(const rational &lhs, 
                         const rational &rhs)
{
    return  rational( lhs.getNum()*rhs.getNum(),
                      lhs.getDen()*rhs.getDen() );
}

main.cpp

#include "rational.h"
int main()
{
    rational r1(1,2);
    rational r2;
    r2 = 2*r1;
    r2 = r1*3;
    return 0;
}

Can someone explain why this is happening ?

Sogger
  • 15,962
  • 6
  • 43
  • 40
Tony_M
  • 69
  • 2
  • 8
  • 1
    Do you need to declare the `operator*` in the .h file? Does it work if you put all the classes and code in-line in main.cpp? – Rup Apr 12 '12 at 15:35
  • yes, its compiling in-line in main.cpp. But why ? – Tony_M Apr 12 '12 at 15:38
  • @Tony_M: Regarding how you don't know about declarations and definitions, yet implement operators, constness and all: Is this even your own code? / oops, you refer to Scott Meyers. I think you should get an introductory book first, not one that manifests and enforces your basic skills. – Sebastian Mach Apr 12 '12 at 15:57

2 Answers2

5

You forgot to tell your users about the existence of your operator:

rational.h

...
const rational operator*(const rational &lhs, 
                         const rational &rhs);
...

Generally, in C as well as in C++, we talk about "definitions" and "declaration". Declarations are annotations to make something visible to someone else, but in itself they do nothing. Definitions are the entititiess that actually do something:

int foo();              // <- we call it "declaration"
int foo() { return 0; } // <- we call it foo's "definition"

In your code, there is no declaration of operator* visible in main.cpp, so you need to provide one somewhere (ideally in your rational's header).

As a style advice: In almost all cases, if a constructor takes builtin types, you want to make it explicit:

explicit rational (int, int);

This prevents sometimes subtle bugs because (in your case) rationals might be unintentionally created (see Automatic Conversions).

Sebastian Mach
  • 38,570
  • 8
  • 95
  • 130
  • +1 for making me look up the 'explicit' keyword http://stackoverflow.com/questions/121162/what-does-the-explicit-keyword-in-c-mean – Sogger Apr 12 '12 at 16:36
  • 2
    @Sogger: be very wary googling for the `explicit` keyword :( – Mooing Duck Apr 12 '12 at 21:32
  • @MooingDuck Ha Ha ha! That's why the link I posted was to here at SO. Google image search: 'explicit' = Kernel Panic! Error: 0x8000NSFW – Sogger Apr 13 '12 at 14:56
3

You haven't declared the operator* in your header file, so it isn't visible in main.cpp.

James Kanze
  • 150,581
  • 18
  • 184
  • 329