未解决的外部符号 -- 模板类

4

可能是重复问题:
C++模板,链接错误

我正在尝试实现选择排序,但我一直收到以下错误(如下所示)。 在我看来,所有的包含和模板都是正确的。 有人能向我解释这个错误的原因以及调试这种类型错误的一般方法吗? 它通常在有包含或模板问题的情况下发生,但偶尔会发生在我不知道出了什么问题的情况下。 谢谢。

错误LNK2019: 未解析的外部符号“public: void __thiscall Selection::SelectionSort(int * const,int)”(?SelectionSort@?$Selection@H@@QAEXQAHH@Z) 在函数_main中引用

test.cpp

#include <iostream>
#include "SelectionSort.h"
using namespace std;

void main()
{
    int ar[] = {1,2,3,4,5};
    Selection<int> s;
    s.SelectionSort(ar,5);

    for(int i = 0; i < 5; i++)
    {

        cout << "\nstudent number " << i + 1<< " grade " << ar[i];
    }
}

SelcectionSort.h

template<class ItemType>
class Selection
{
public:
    void SelectionSort(ItemType[], int);
private:
    int MinIndex(ItemType[], int, int);
    void Swap(ItemType& , ItemType&);
};

SelectionSort.cpp

#include "SelectionSort.h"

template<class ItemType>
void Selection<ItemType>::SelectionSort(ItemType values[], int numValues)
// Post: The elements in the array values are sorted by key.
{
int endIndex = numValues-1;
for (int current = 0; current < endIndex; current++)
Swap(values[current],
values[MinIndex(values, current, endIndex)]);
}

template<class ItemType>
int Selection<ItemType>::MinIndex(ItemType values[], int startIndex, int endIndex)
// Post: Returns the index of the smallest value in
// values[startIndex]..values[endIndex].
{
int indexOfMin = startIndex;
for (int index = startIndex + 1; index <= endIndex; index++)
if (values[index] < values[indexOfMin])
indexOfMin = index;
return indexOfMin;
}

template<class ItemType>
inline void Selection<ItemType>::Swap(ItemType& item1, ItemType& item2)
// Post: Contents of item1 and item2 have been swapped.
{
ItemType tempItem;
tempItem = item1;
item1 = item2;
item2 = tempItem;
}

@DavidRodríguez-dribeas 刚刚做了。 - PiotrNycz
1个回答

9
SelectionSort.cpp 的内容移至类声明后的 SelectionSort.h 中。还需确保在整个 .h 文件的内容周围加上头文件保护。 问题出在C++实现模板时的处理方式。每次遇到与模板类(如Selection<int>)一起使用的新类型,它都会重新创建整个类,并将 ItemType 替换为 int。 因此,编译时需要知道类的完整定义(以及其方法)。它不能只使用类定义并推迟链接到稍后。

谢谢回复。之前我在将代码分离为声明和实现文件时使用过模板。当我回顾那些项目时,我发现它们似乎没有什么区别。你知道是什么原因让以前的项目可以编译吗? - Zzz
我刚想起来我是怎么让它们编译通过的。我添加了包含保护并在测试驱动程序中包含了.cpp实现文件。这样做如何改变编译以使一切正常工作? - Zzz
@Azzi,底线是编译器需要在编译test.cpp文件时能够看到你的模板类的完整实现。包含CPP文件可以工作,因为编译器随后可以访问完整的实现细节,但我始终认为这比它值得的更加混乱。 - riwalk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接