C++ 使用模板时发生链接器错误

C++ 使用模板时发生链接器错误,c++,visual-studio-2010,templates,c++11,linker-errors,C++,Visual Studio 2010,Templates,C++11,Linker Errors,我正在用我的项目做一个受控的学习实验,它包括创建我自己的集合和迭代器,基本上是一个数组和一个链表。由于它编译时带有链接错误,所以我缺少了一些东西。我花了三天的时间检查、编码和重新编码,我真的需要一些帮助 我正在使用VisualStudio2010。我正在涉猎新的C++11内容,以及新的基于Range的for,或者我认为的每个for。Visual C++中的每一个代码都是< >(VAR在列表中)< /C>,但是在GCC中,它是(var:list)< /> > < /p> 以下是链接器错误: mai

我正在用我的项目做一个受控的学习实验,它包括创建我自己的集合和迭代器,基本上是一个数组和一个链表。由于它编译时带有链接错误,所以我缺少了一些东西。我花了三天的时间检查、编码和重新编码,我真的需要一些帮助

我正在使用VisualStudio2010。我正在涉猎新的C++11内容,以及新的基于Range的for,或者我认为的每个for。Visual C++中的每一个代码都是< >(VAR在列表中)< /C>,但是在GCC中,它是<代码>(var:list)< /> > < /p> 以下是链接器错误:

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)
main.obj:错误LNK2001:未解析的外部符号“public:virtual class Iterator\uu thiscall Container::begin(void)const”(?begin@$Container@H@@UBE?AV$Iterator@H@@XZ)
main.obj:错误LNK2001:未解析的外部符号“public:虚拟类迭代器\uu thiscall Container::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();
}
模板
类迭代器
{
公众:
迭代器(T*Start):当前(Start){
常量T&运算符*()常量{return*Current;}
常量T*运算符->()常量{返回当前;}
迭代器和运算符++(){Current++;return*this;}
布尔运算符!=(迭代器和其他){返回当前值!=Other.Current;}
受保护的:
T*电流;
};
样板
类容器
{
公众:
容器():计数(0){}
容器(无符号整数计数):计数(计数){
无符号int GetCount()常量{return Count;}
bool IsEmpty()常量{return Count==0;}
迭代器&GetIterator()常量{return begin()};
//与基于C++0x范围的for兼容需要begin()和end()函数。
虚拟迭代器begin()常量;
虚拟迭代器end()常量;
受保护的:
无符号整数计数;
};
样板
类ArrayList:公共容器
{
公众:
ArrayList():项(nullptr),容器(0){}
虚拟迭代器begin()常量
{ 
返回迭代器(Items);
}
虚拟迭代器end()常量
{ 
返回迭代器(Items+Count);
}
私人:
T*项目;
};
int main()
{
ArrayList MyList;
对于每个(MyList中的自动项目)
{ }
返回MyList.GetCount();
}

<代码> >每个微软代码。C++,AKA,C++,CLI。真正的C++11版本实际上是
for(type&var:container)

接下来,您没有在
容器中实现
开始
结束
方法
最后,虚拟函数仅在使用指向基类型的指针时使用,例如:

Container*myCont=newarraylist();
自动it=myCont->begin();

将调用
ArrayList::begin()
函数。对于容器来说,虚拟函数实际上是没有用的(没有双关语)。

< p> <代码>对于每个< /代码>是微软.NET,例如托管C++ + AKA C++/CLI。真正的C++11版本实际上是
for(type&var:container)

接下来,您没有在
容器中实现
开始
结束
方法
最后,虚拟函数仅在使用指向基类型的指针时使用,例如:

Container*myCont=newarraylist();
自动it=myCont->begin();

将调用
ArrayList::begin()
函数。Aka,对于容器来说,虚拟函数实际上是无用的(没有双关语)。

看起来很简单,在集合类中开始和结束函数的实现在哪里

virtual Iterator<T> begin() const;
virtual Iterator<T> end() const;
虚拟迭代器begin()常量;
虚拟迭代器end()常量;

您必须为其中每一个都指定一个实现,这就是导致链接器错误的原因。

看起来很简单,在集合类中,begin和end函数的实现在哪里

virtual Iterator<T> begin() const;
virtual Iterator<T> end() const;
虚拟迭代器begin()常量;
虚拟迭代器end()常量;

您必须为其中每一个都指定一个实现,这就是导致链接器错误的原因。

在容器类中,您应该声明begin()和end():

虚拟迭代器begin()const=0;
虚拟迭代器end()常量=0;

在容器类中,您应该将begin()和end()声明为:

虚拟迭代器begin()const=0;
虚拟迭代器end()常量=0;

每当基类包含非纯虚拟方法时,您都需要在某个地方定义它们。否则,在创建派生类对象时,它将给出链接器错误,例如,未定义的引用/symbol。 如果您不想定义
Container::begin()
Container::end()
,那么将它们声明为
纯虚拟


这里,我有。

每当基类包含非纯虚拟方法时,您需要在某个地方定义它们。否则,在创建派生类对象时,它将给出链接器错误,例如,未定义的引用/symbol。 如果您不想定义
Container::begin()
Container::end()
,那么将它们声明为
纯虚拟


这里,我有。

即使它被实现了,它也应该和声明一起,如果你把它放在一个.cpp文件中,你仍然会得到链接错误。因为Container似乎是一个抽象的Container类,所以最好将这些方法变成纯虚拟的,但他现在显然正在尝试使用这个类,并指出需要一个实现,这会让他自己思考这些逻辑和设计决策。即使实现了,它也应该与声明一起,如果你把它放在一个.cpp文件中,你仍然会得到链接错误。由于Container似乎是一个抽象的Container类,因此最好将这些方法变成纯虚拟的。这两种情况都是正确的,但他显然正在尝试使用这个类,并指出需要有一个实现
virtual Iterator<T> begin() const = 0;
virtual Iterator<T> end() const = 0;