问题
This is the smallest contained example I can think of. First the header of the class. This class should simply print the one double it contains whenever the << operator is used.
#pragma once
#ifndef EURO_H
#define EURO_H
#include <ostream>
namespace EU
{
class Euro final
{
public:
explicit Euro(double value);
virtual ~Euro() = default;
double getValue() const;
friend std::ostream& operator<<(std::ostream &os, const Euro &euro);
private:
double m_value;
};
}
#endif // EURO_H
Now the .cpp
#include "euro.h"
using namespace EU;
Euro::Euro(double value)
{
m_value = value;
}
double Euro::getValue() const
{
return m_value;
}
std::ostream& operator<<(std::ostream &os, const Euro &euro)
{
os << euro.getValue() << "EUR";
return os;
}
And finally, the main.cpp
#include "euro.h"
#include <iostream>
using namespace EU;
int main()
{
auto e = Euro(3.14);
std::cout << e << std::endl;
}
However, when I compile this using:
g++ -std=c++11 *.cpp
it spits out the following error:
/tmp/ccP7OKC5.o: In function `main':
main.cpp:(.text+0x35): undefined reference to `EU::operator<<(std::ostream&, EU::Euro const&)'
collect2: error: ld returned 1 exit status
What am I doing wrong?
Kind regards, Joris
回答1:
You're expecting using namespace EU;
to put all the subsequent code inside namespace EU
, but it won't (otherwise your int main
would be in the namespace too!). This just brings things already in that namespace into scope.
It means that you're declaring the friend function inside the namespace, but defining a new function in the global scope. Calls to the former will fail because there's no definition for it.
Remove the using namespace
, and wrap namespace EU { }
around everything in euro.cpp
.
回答2:
Change your cpp file from this:
#include "euro.h"
using namespace EU;
Euro::Euro(double value)
{
m_value = value;
}
double Euro::getValue() const
{
return m_value;
}
std::ostream& operator<<(std::ostream &os, const Euro &euro)
{
os << euro.getValue() << "EUR";
return os;
}
to this:
#include "euro.h"
namespace EU {
Euro::Euro(double value)
{
m_value = value;
}
double Euro::getValue() const
{
return m_value;
}
std::ostream& operator<<(std::ostream &os, const Euro &euro)
{
os << euro.getValue() << "EUR";
return os;
}
} // namespace EU
This defines the code within this cpp file to be within the namespace. What you was previously doing was declaring your namespace to be used at the global scope of that file as you were not defining your source code to be within the namespace.
来源:https://stackoverflow.com/questions/36776051/how-to-overload-the-operator-from-within-a-namespace