2016-04-21 83 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文件中的代碼是命名空間內。你之前做的是聲明你的名字空間在該文件的全局範圍內使用,因爲你並沒有將你的源代碼定義在命名空間中。