2016-04-21 86 views
2

这是我能想到的最小的包含示例。 首先是班级的标题。只要使用< <运算符,此类应该只打印它包含的一倍。如何超载运算符<<从命名空间内

#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 

现在的.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; 
} 

最后,main.cpp中

#include "euro.h" 

#include <iostream> 

using namespace EU; 

int main() 
{ 
    auto e = Euro(3.14); 
    std::cout << e << std::endl; 
} 

然而,当我编译这个使用:

g++ -std=c++11 *.cpp 

它吐出来出现以下错误:

/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 

我在做什么错?

亲切的问候, 里斯

+0

您可以进一步剥离它,因为它没有'value',只是[尝试]打印一个静态值! –

+0

作为一个提示,你不需要'#pragma once'和标头守卫#ifndef ... #define ....#endif' –

回答

9

你希望using namespace EU;把所有后续的代码中namespace EU,但它不会(否则你int main将在命名空间呢!)。这只是将该名称空间中已有的内容纳入范围。

这意味着你声明了名字空间中的朋友函数,但是在全局范围中定义了一个新的函数。呼吁前者将失败,因为没有定义它。

删除using namespace,并将namespace EU { }围绕在euro.cpp的所有内容中。

0

从此改变你的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; 
} 

这样:

#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 

这定义了此CPP文件中的代码是命名空间内。你之前做的是声明你的名字空间在该文件的全局范围内使用,因为你并没有将你的源代码定义在命名空间中。