了解 Visual Studio 2010 中的此错误 (LNK 2019)

Posted

技术标签:

【中文标题】了解 Visual Studio 2010 中的此错误 (LNK 2019)【英文标题】:Understanding this error (LNK 2019) in Visual Studio 2010 【发布时间】:2012-10-10 20:31:11 【问题描述】:

好吧,我正在处理一个 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;

另外,Record 类:

class Record

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

private:
char key;

;

【问题讨论】:

你的函数模板中DataType在哪里使用? DataType 是 KeyType 在列表中跟踪的内容。关键是保持数据成员有序。就像 account amount 是一个 float DataType 一样,account number 是 int KeyType。 【参考方案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&lt;DataType, KeyType&gt;::binarySearch 的链接器不把它算作指定函数??!

【讨论】:

就是这样。好电话!我到处寻找错误。只是我忘了给函数添加作用域。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

让我们逐行分解:

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 的类型为 Record,但您不知道 KeyType 是什么。

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

这是上面函数的重命名。


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

也就是说,你没有提供DataType,所以编译器不知道如何生成函数模板binarySearch的模板特化。

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

【讨论】:

+1 这个解释非常有用!非常感谢您的帮助。

以上是关于了解 Visual Studio 2010 中的此错误 (LNK 2019)的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio Post-build 事件:for %f in (set) command

Visual Studio 2017 中的 Visual Studio 2010

Visual Studio 2010 Professional 中的 /analyze 标志

visual studio 2010中调用另外一个项目中的方法

似乎无法忽略 Visual Studio 2010 中的库

Visual Studio 2010 中的传输文件功能