2011-04-14 59 views
1

我正在嘗試使用我的項目進行受控學習實驗,它涉及到創建我自己的集合和迭代器,本質上是一個數組和鏈接列表。有些東西因爲編譯鏈接錯誤而丟失。我花了三天時間檢查,編碼和重新編碼,我真的需要一些幫助。使用模板時的鏈接器錯誤

我使用Visual Studio 2010中,我在涉足新的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 " ([email protected][email protected]@@[email protected]@@XZ) 
main.obj : error LNK2001: unresolved external symbol "public: virtual class Iterator<int> __thiscall Container<int>::end(void)const " ([email protected][email protected]@@[email protected]@@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(); 
} 

回答

1

在容器類,你應該申報開始()和end()爲:

virtual Iterator<T> begin() const = 0; 
virtual Iterator<T> end() const = 0; 
+0

很難想象這麼簡單的人可以讓我堅持這麼久。謝謝。我的目標是在Container上獲得純虛擬。 – 2011-04-14 13:32:36

1

for each是微軟.NET,例如。託管C++又名C++/CLI。真正的C++ 11版本真的是for(type& var : container)
接下來,您在Container中沒有實施您的beginend方法。
最後,使用指針到基本類型,例如:

Container* myCont = new ArrayList<int>(); 
auto it = myCont->begin(); 

能打電話通知ArrayList<int>::begin()功能時虛函數只有使用。也就是說,對於容器來說,虛擬功能實際上是無用的(不是雙關語)。

+0

Visual C++'for each,in'具有基於C++ 0x範圍的所有功能,只是語法不同。看到這篇文章:http://msdn.microsoft.com/en-us/library/ms177202(v=VS.100).aspx – 2011-04-14 13:49:28

4

看起來很簡單,你在Collection類中的開始和結束函數的實現在哪裏?

virtual Iterator<T> begin() const; 
virtual Iterator<T> end() const; 

您必須爲每個指定的實現,這是什麼導致鏈接器錯誤。

+0

即使它被實現,它應該與聲明一起,如果你把它放在一個.cpp文件,你仍然會得到鏈接錯誤。由於Container似乎是一個抽象的容器類,所以將這些方法變爲純虛擬似乎更好。 – fbafelipe 2011-04-14 04:44:00

+0

這兩件事情都是真實的,但他顯然正試圖利用現在的班級,並指出需要有一個實施應該引導他自己思考那些邏輯和設計決定。 – radman 2011-04-14 04:49:21

1

每當一個基類包含非純虛方法,你需要的地方定義它們。否則,在創建派生類對象時,它會給出鏈接器錯誤,例如,未定義的引用/符號。 如果您不想定義Container::begin()Container::end(),則將它們聲明爲pure virtual。我有answered a similar question