[英]Linker error when using templates
我正在嘗試對項目進行受控的學習實驗,它涉及創建自己的集合和迭代器,本質上是一個數組和一個鏈表。 我缺少一些東西,因為它編譯時帶有鏈接錯誤。 我花了三天時間對此進行檢查,編碼和重新編碼,我確實需要一些幫助。
我使用的是Visual Studio2010。我涉足新的C ++ 11,其中包含基於的新范圍 ,或我認為的每個 范圍 。 在Visual C ++中,它for each (VAR in LIST)
,但在GCC中,它for (VAR : LIST)
。
這是鏈接器錯誤:
main.obj : error LNK2001: unresolved external symbol "public: virtual class Iterator<int> __thiscall Container<int>::begin(void)const " (?begin@?$Container@H@@UBE?AV?$Iterator@H@@XZ)
main.obj : error LNK2001: unresolved external symbol "public: virtual class Iterator<int> __thiscall Container<int>::end(void)const " (?end@?$Container@H@@UBE?AV?$Iterator@H@@XZ)
我的代碼如下:
template<typename T>
class Iterator
{
public:
Iterator(T* Start) : Current(Start) { }
const T& operator*() const { return *Current; }
const T* operator->() const { return Current; }
Iterator<T>& operator++() { Current++; return *this; }
bool operator!=(Iterator<T> &Other) { return Current != Other.Current; }
protected:
T* Current;
};
template<typename T>
class Container
{
public:
Container() : Count(0) { }
Container(unsigned int Count) : Count(Count) { }
unsigned int GetCount() const { return Count; }
bool IsEmpty() const { return Count == 0; }
Iterator<T>& GetIterator() const { return begin() };
// Compatibility with C++0x range-based for requires begin() and end() functions.
virtual Iterator<T> begin() const;
virtual Iterator<T> end() const;
protected:
unsigned int Count;
};
template<typename T>
class ArrayList : public Container<T>
{
public:
ArrayList() : Items(nullptr), Container(0) { }
virtual Iterator<T> begin() const
{
return Iterator<T>(Items);
}
virtual Iterator<T> end() const
{
return Iterator<T>(Items + Count);
}
private:
T *Items;
};
int main()
{
ArrayList<int> MyList;
for each (auto Item in MyList)
{ }
return MyList.GetCount();
}
看起來很簡單,Collection類中begin和end函數的實現在哪里?
virtual Iterator<T> begin() const;
virtual Iterator<T> end() const;
您必須為每個選項都具有指定的實現,這就是導致鏈接器錯誤的原因。
for each
都是Microsoft .NET,例如。 托管C ++,又稱C ++ / CLI。 真正的C ++ 11版本實際上是for(type& var : container)
。
接下來,您沒有在Container
實現begin
和end
方法。
最后, 僅在使用指向基礎類型的指針時使用虛函數,例如:
Container* myCont = new ArrayList<int>();
auto it = myCont->begin();
將調用ArrayList<int>::begin()
函數。 也就是,對於容器而言,虛擬功能實際上是無用的(無雙關語)。
在Container類中,應將begin()和end()聲明為:
virtual Iterator<T> begin() const = 0;
virtual Iterator<T> end() const = 0;
只要基類包含非純虛方法,就需要在某個地方定義它們。 否則,在創建Derived類對象時,它將給出鏈接器錯誤,例如undefined reference / symbol 。 如果您不想定義Container::begin()
和Container::end()
則將它們聲明為pure virtual
。
在這里,我已經回答了類似的問題 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.