OK, so I can get my code to work, but there's something that's bugging me. It has to do with operator overloading and making non-member functions inline. Here's a very simple program that implements a complex number object:
Contained in Complex.h
using namespace std;
class Complex {
private:
double real;
double imaginary;
public:
Complex(void);
Complex(double r, double i);
double getReal();
double getImaginary();
string toString();
};
inline Complex operator+(Complex lhs, Complex rhs);
...and in Complex.cc
#include <sstream>
#include <string>
#include "Complex.h"
using namespace std;
Complex::Complex(void)
{
...not important...
}
Complex::Complex(double r, double i)
{
real = r;
imaginary = i;
}
double Complex::getReal()
{
return real;
}
double Complex::getImaginary()
{
return imaginary;
}
string Complex::toString()
{
...what you would expect, not important here...
}
inline Complex operator+(Complex lhs, Complex rhs)
{
double result_real = lhs.getReal() + rhs.getReal();
double result_imaginary = lhs.getImaginary() + rhs.getImaginary();
Complex result(result_real, result_imaginary);
return(result);
}
and finally in plus_overload_test.cc
using namespace std;
#include <iostream>
#include "Complex.h"
int main(void)
{
Complex c1(1.0,3.0);
Complex c2(2.5,-5.2);
Complex c3 = c1 + c2;
cout << "c3 is " << c3.toString() << endl;
return(0);
}
Compiling with g++ using a makefile that does the linking this produces the error:
plus_overload_test.cc:(.text+0x5a): undefined reference to `operator+(Complex, Complex)'
If I just remove the "inline" from before the operator+ in Complex.h and Complex.cc then everything compiles and works as it should. Why does the inline modifier cause this error? Everyone, for example:
and
http://en.cppreference.com/w/cpp/language/operators
seems to recommend that for overloading binary operators the functions should be non-member and inline. So why am I encountering an error when I make them inline?
And, yes, I realize that the inline modifier may be a red herring since modern compilers should take care of this. But I remain curious.
Cheers!
An inline
function must be defined in every file where it's used.
In case you want the precise wording from the standard (§7.1.2/4):
An inline function shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case.
With it marked inline
, but defined in only one translation unit, you weren't meeting your side of your contract with the compiler (so to speak).