簡體   English   中英

使用模板時的鏈接器錯誤

[英]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實現beginend方法。
最后, 在使用指向基礎類型的指針時使用虛函數,例如:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM