2012-07-25 139 views
1

我昨天發佈了這個。人們建議我應該有Point.hPoint.cpp文件,因爲我使用的是template。我爲我的課程Point創建了單獨的文件,但仍然收到錯誤消息。C++中的「未定義符號」錯誤

//Point.h 
Point(T = 0, T = 0, string = "Deafault Point"); 
~Point(); 
T operator-(const Point<T> &); 

//Point.cpp 
template < typename T > 
Point<T>::Point(T x,T y, string name) 
:X(x), Y(y), Name(name) 
{ 
} 

template < typename T > 
Point<T>::~Point() 
{ 
} 

template < typename T> 
T Point<T>::operator-(const Point<T> &rhs) 
{ 
cout << "\nThe distance between " << getName() << " and " 
<< rhs.getName() << " = "; 

return sqrt(pow(rhs.getX() - getX(), 2) + pow(rhs.getY() - getY(), 2));; 
} 

//main.cpp 
#include <iostream> 
#include <math.h> 
#include "Point.h" 

using namespace std; 

int main() { 

Point<double> P1(3.0, 4.1, "Point 1"); 
cout << P1; 

Point<double> P2(6.4, 2.9, "Point 2"); 
cout << P2; 

cout << (P2 - P1); 
return EXIT_SUCCESS; 
} 

這是我得到:

Undefined symbols: 
"std::basic_ostream<char, std::char_traits<char> >& operator<< <double (std::basic_ostream<char, std::char_traits<char> >&, Point<double> const&)", referenced from: 
    _main in main.o 
    _main in main.o 
"Point<double>::operator-(Point<double> const&)", referenced from: 
    _main in main.o 
"Point<double>::Point(double, double, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)", referenced from: 
    _main in main.o 
    _main in main.o 
"Point<double>::~Point()", referenced from: 
    _main in main.o 
    _main in main.o 
    _main in main.o 
    _main in main.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

任何幫助表示讚賞...

+0

您用於構建可執行文件的確切命令是什麼? – YePhIcK 2012-07-25 01:24:09

+0

你發佈的代碼甚至都不是很正確。也許閱讀一本關於C++的好書介紹? – 2012-07-25 01:25:04

+1

僅供參考您的'operator-'不是強制返回類型T.'sqrt()'總是返回一個double。不一定是編譯錯誤之一,但如果你做了一個'Point ' – Russ 2012-07-25 01:29:46

回答

7

人建議我應該有Point.h和Point.cpp文件,因爲我m使用模板

無論誰提出這是錯誤的。模板的實現必須可見

你可以分開執行到一個文件,但你需要包括它以及之後。當你可以隱藏模板的實現時,唯一的情況是當你知道特殊化並且事先聲明它們時。 (這並不適用於此)

您需要爲模板單個文件:

//Point.h 

template <typename T> 
struct Point 
{ 
    Point(T = 0, T = 0, string = "Deafault Point"); 
    ~Point(); 
    T operator-(const Point<T> &); 
}; 

template < typename T > 
Point<T>::Point(T x,T y, string name) 
:X(x), Y(y), Name(name) 
{ 
} 

template < typename T > 
Point<T>::~Point() 
{ 
} 

template < typename T> 
T Point<T>::operator-(const Point<T> &rhs) 
{ 
cout << "\nThe distance between " << getName() << " and " 
<< rhs.getName() << " = "; 

return sqrt(pow(rhs.getX() - getX(), 2) + pow(rhs.getY() - getY(), 2));; 
} 

而且,在頭裸string建議您在標題中有一個using namespace std;爲好。這是不好的做法,請刪除using指令並限定名稱std::string

+0

它的工作!謝謝:) – 2012-07-25 01:43:46

0

有關模板類的所有已定義和已實現的代碼應該寫入'.h'文件,否則將會出現編譯錯誤。

+0

不完全正確。實現需要可見,但不一定在'.h'文件中。即使這樣,如果你事先知道所有的專業化。 – 2012-07-25 01:29:29