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