2010-06-03 91 views
1

我對以前的文章有一些很好的見解,但我不知道這些編譯錯誤是什麼意思,我可以使用一些助手。模板,朋友,超載都是新的,所以3合1是給我一些問題......朋友,模板,重載<<鏈接器錯誤

1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Point<double>::Point<double>(double,double)" ([email protected]@@[email protected]@Z) referenced in function _main 
1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall Point<int>::Point<int>(int,int)" ([email protected]@@[email protected]@Z) referenced in function _main 
1>C3_HW8.exe : fatal error LNK1120: 3 unresolved externals 

Point.h

#ifndef POINT_H 
#define POINT_H 

#include <iostream> 

template <class T> 
class Point 
{ 
public: 
Point(); 
Point(T xCoordinate, T yCoordinate); 
template <class G> 
friend std::ostream &operator<<(std::ostream &out, const Point<G> &aPoint); 

private: 
T xCoordinate; 
T yCoordinate; 
}; 

#endif 

Point.cpp

#include "Point.h" 

template <class T> 
Point<T>::Point() : xCoordinate(0), yCoordinate(0) 
{} 

template <class T> 
Point<T>::Point(T xCoordinate, T yCoordinate) : xCoordinate(xCoordinate), yCoordinate(yCoordinate) 
{} 


template <class G> 
std::ostream &operator<<(std::ostream &out, const Point<G> &aPoint) 
{ 
std::cout << "(" << aPoint.xCoordinate << ", " << aPoint.yCoordinate << ")"; 
return out; 
} 

主.cpp

#include <iostream> 
#include "Point.h" 

int main() 

    { 
    Point<int> i(5, 4); 
    Point<double> *j = new Point<double> (5.2, 3.3); 
    std::cout << i << j; 
    } 
+1

順便說一句,那些鏈接器錯誤,而不是編譯器錯誤。問題在於編譯器從不編譯模板函數定義,因爲它不知道要編譯它們的「T」。 – Troubadour 2010-06-03 21:51:13

回答

5

對於大多數編譯器,喲您需要將模板放在標題中,以便編譯器在使用它們時可以看到它們。如果你真的想避免這種情況,你可以在必要的類型上使用模板的顯式實例化,但是將它們放在標題中更爲常見。

0

Point類是否與主函數在同一個項目中定義和編譯?由於模板在編譯時已解析,因此無法在第二個項目中定義模板,例如靜態庫,並對其進行鏈接。如果你想在一個單獨的項目中使用它,你需要在頭文件中提供完整的實現,並簡單地省略模板的源文件。在包含這個頭文件的時候,當你的主函數文件被編譯時,模板將被編譯爲它的實際實例,在你的案例Point和Point中。

請記住,這需要任何鏈接才能使用該類,並且只包含模板標頭的項目不會產生可鏈接的lib。