1

好的,所以我正在开发一个 C++ 项目,但我不知道如何缓解这个链接器错误。下面是:

1>test4.obj : 错误 LNK2019: 未解析的外部符号“private: bool __thiscall OrderedList::binarySearch(char,int &)” (?binarySearch@?$OrderedList@VRecord@@D@@AAE_NDAAH@Z) 在函数中引用“ public: virtual void __thiscall OrderedList::insert(class Record const &)" (?insert@?$OrderedList@VRecord@@D@@UAEXABVRecord@@@Z)

如果有人可以帮助分解并向我翻译 Visual Studio 2010 所说的那将是惊人的(我真的想更好地阅读输出)。我一直在阅读这个特定的错误,但我仍然不明白为什么它会应用于我的代码。

编辑: binarySearch 方法正在 OrderedList.cpp 文件中实现。我还在包含我的主文件的文件中使用#include "OrderedList.cpp" 语句。

有问题的两个功能:

插入原型:

virtual void insert ( const DataType &newDataItem ) throw ( logic_error );

插入:

template <typename DataType, typename KeyType>
void OrderedList<DataType, KeyType>::insert(const DataType &newDataItem) 
throw (logic_error ) {
int index = 0;
if (size == maxSize) {
    throw logic_error("List is full.");
} 
else { 
    KeyType searchKey = newDataItem.getKey();
    if (binarySearch(searchKey, index)) {
        cursor = index;
        dataItems[cursor] = newDataItem;
    }
    else {
        cursor = index;
        insert(newDataItem);
    }
} 
}

二分搜索原型:

bool binarySearch ( KeyType searchKey, int &index );

二进制搜索:

template < typename DataType, typename KeyType >
bool binarySearch (KeyType searchKey, int &index ) {
int low  = 0;        // Low index of current search range
int high = size - 1;    // High index of current search range
bool result;            // Result returned

while ( low <= high )
{
    index = ( low + high ) / 2;               // Compute midpoint
    if ( searchKey < dataItems[index].getKey() )
       high = index - 1;                      // Search lower half
    else if ( searchKey > dataItems[index].getKey() )
       low = index + 1;                       // Search upper half
    else
       break;                                 // searchKey found
}

if ( low <= high )
   result = true;       // searchKey found
else
{
   index = high;        // searchKey not found, adjust index
   result = false;
}

return result;
}

此外,记录类:

class Record
{
public: 
Record () { key = char(0); }
void setKey(char newKey) { key = newKey; }
char getKey() const { return key; }

private:
char key;

};

4

3 回答 3

1

除非您使用正确的模板参数调用模板函数,否则模板函数并不是真正的函数。在这种情况下,由于 OrderedList.cpp 文件不包含函数调用,因此从未生成实际的函数代码。这就是链接器找不到它的原因。

通常在头文件中定义模板函数或类来避免这个问题。

于 2012-10-10T20:44:43.027 回答
1

这条线是否可能:

template < typename DataType, typename KeyType >
bool binarySearch (KeyType searchKey, int &index )

在您的 cpp 文件中,您只是忘记将其实现为:

template < typename DataType, typename KeyType >
bool OrderedList<DataType, KeyType>::binarySearch(KeyType searchKey, int &index)

然后binarySearch只是一个全局函数,而不是来自OrderedList试图找到的链接器的函数,OrderedList<DataType, KeyType>::binarySearch不要将其视为指定函数??!

于 2012-10-10T20:58:53.170 回答
1

让我们逐行分解:

1>test4.obj : error LNK2019: unresolved external symbol 

这告诉您在 test4.obj 文件中,编译器无法找到它期望可用的编译对象。

"private: bool __thiscall OrderedList::binarySearch(char,int &)" 

这是无法找到的对象(在本例中为成员函数)的函数签名。

(?binarySearch@?    $OrderedList@VRecord@@D@@AAE_NDAAH@Z) 

这是上述函数的“变形名称”——编译器在目标文件中给出的名称。它为编译器提供了一种文本方式来验证名称相似但类型关联不同的对象。

referenced in function 

这一行告诉您下一个对象将是引用未解析符号的位置。

"public: virtual void __thiscall OrderedList::insert(class Record const &)"

这是调用导致错误的符号的对象的函数签名。请注意,模板参数在这里是不可见的,但任何类型绑定的参数都是可见的,所以你知道DataType是 type Record,但你不知道是什么KeyType

(?insert@?$OrderedList@VRecord@@D@@UAEXABVRecord@@@Z)

这是上述函数的错位名称。


现在,让我们看看这意味着什么。您有一个模板方法正在调用似乎是全局函数模板的东西。该全局函数模板有两个模板参数,其中只有一个由函数调用提供。

换句话说,您没有提供DataType,因此编译器不知道如何生成函数 template 的模板特化binarySearch

这里的好消息是您实际上并不需要DataType模板参数,因此您应该可以简单地消除它。那时,您的函数模板将完全专业化并且应该可以编译。

于 2012-10-10T21:02:58.870 回答