【问题标题】:C++ keep getting error LNK2019: unresolved external symbol [duplicate]C ++不断收到错误LNK2019:无法解析的外部符号[重复]
【发布时间】:2012-04-22 20:22:36
【问题描述】:

我尝试用谷歌搜索,但总是遇到不同的问题。当我尝试编译这个程序时,我得到了 3 个未解决的外部:

1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall DynIntStack<char>::~DynIntStack<char>(void)" (??1?$DynIntStack@D@@QAE@XZ) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall DynIntStack<char>::pop(char &)" (?pop@?$DynIntStack@D@@QAEXAAD@Z) referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall DynIntStack<char>::push(char)" (?push@?$DynIntStack@D@@QAEXD@Z) referenced in function _main

DynIntStack.h

/****************************************************************************
DynIntStack class.

Chad Peppers

This class creates a object for stacking nodes

In addition, there should be member functions to perform the following 
operations:
- Push to the stack
- Pop to the stack
- Function to check if empty

****************************************************************************/
// Specification file for the DynIntStack class
#ifndef DYNINTSTACK_H
#define DYNINTSTACK_H

template <class T>
class DynIntStack
{
private:
   // Structure for stack nodes
   struct StackNode
   {
      T value;        // Value in the node
      StackNode *next;  // Pointer to the next node
   };

   StackNode *top;      // Pointer to the stack top

public:
   // Constructor
   DynIntStack()
      {  top = NULL; }

   // Destructor
   ~DynIntStack();

   // Stack operations
   void push(T);
   void pop(T &);
   bool isEmpty();
}; 
#endif

DynIntStack.cpp

/****************************************************************************
DynIntStack class.

Chad Peppers

This class creates a object for stacking nodes

In addition, there should be member functions to perform the following 
operations:
- Push to the stack
- Pop to the stack
- Function to check if empty

****************************************************************************/

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

/*************************************************************************
Basic class constructor.

Input Parameters:  Information to build the  stack

Return Type:  void

*************************************************************************/

template<class T>
DynIntStack<T>::~DynIntStack()
{
   StackNode *nodePtr, *nextNode;

   // Position nodePtr at the top of the stack.
   nodePtr = top;

   // Traverse the list deleting each node.
   while (nodePtr != NULL)
   {
      nextNode = nodePtr->next;
      delete nodePtr;
      nodePtr = nextNode;
   }
}

/*************************************************************************
Function to push an item in the stack

Input Parameters:  T

Return Type:  void

*************************************************************************/

template<class T>
void DynIntStack<T>::push(T num)
{
   StackNode *newNode; // Pointer to a new node

   // Allocate a new node and store num there.
   newNode = new StackNode;
   newNode->value = num;

   // If there are no nodes in the list
   // make newNode the first node.
   if (isEmpty())
   {
      top = newNode;
      newNode->next = NULL;
   }
   else  // Otherwise, insert NewNode before top.
   {
      newNode->next = top;
      top = newNode;
   }
}

/*************************************************************************
Function to pop an item in the stack

Input Parameters:  T

Return Type:  void

*************************************************************************/
template<class T>
void DynIntStack<T>::pop(T &num)
{
   StackNode *temp; // Temporary pointer

   // First make sure the stack isn't empty.
   if (isEmpty())
   {
      cout << "The stack is empty.\n";
   }
   else  // pop value off top of stack
   {
      num = top->value;
      temp = top->next;
      delete top;
      top = temp;
   }
}

/*************************************************************************
Basic class deconstructor.

Input Parameters:  None

Return Type:  void

*************************************************************************/
template<class T>
bool DynIntStack<T>::isEmpty()
{
   bool status;

   if (!top)
      status = true;
   else
      status = false;

   return status;
}

ma​​in.cpp

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

int main(){

    int value = 0;
    char value2;
    //DynIntStack<int> stack;
    DynIntStack<char> stack1;

    cout << "Pushing 1\n";
    stack1.push('T');
    stack1.pop(value2);
    cout << value2;

    system("pause");
    return 0;
}

【问题讨论】:

    标签: c++ templates linker


    【解决方案1】:

    您需要将 .cpp 文件中的所有模板实现放在头文件中,或者放在头文件中包含的文件中。并且不要试图编译实现文件。一些系统试图编译带有 .cpp 后缀的文件。编译器需要查看代码才能实例化模板。

    【讨论】:

    • 如果我每次看到这个问题都有一磅
    • @EdChum 或点赞 :-)
    • @juanchopanza 是的,是我对你投了赞成票,似乎我们每 2-3 天就会收到这些模板链接器错误
    • 非常令人沮丧!那只是在模板上?
    • @Chad 是的。将模板视为在编译时需要特定模板参数才能被实例化的部分代码。编译器基本上从模板中生成代码。这必须在编译之前发生。我希望这是有道理的......
    【解决方案2】:

    在 DynIntStack.h 的底部,放置

    #include <DynIntStack.cpp>
    

    发生的事情是编译器看不到模板实现代码,因此无法为它发出任何内容。

    【讨论】:

      【解决方案3】:

      解决问题最简单的方法是:

      无论您想在哪里包含您的模板类,例如“DynIntStack.h” 而是做“DynIntStack.cpp”。例如在上面的 main.cpp 中。

      就这么简单,无需更改任何其他内容。

      【讨论】:

      • 为什么这个答案被否决了,因为该解决方案确实有效?
      • 其他答案说同样的事情,而且是 2 年前。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      • 2013-01-28
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多