2012-04-22 30 views
6

Intenté googlear esto pero siempre vuelvo con diferentes problemas. Estoy recibiendo 3 externos sin resolver cuando intento compilar este programa:C++ sigue recibiendo el error LNK2019: símbolo externo sin resolver

1>main.obj : error LNK2019: unresolved external symbol "public: __thiscall DynIntStack<char>::~DynIntStack<char>(void)" ([email protected]@@[email protected]) referenced in function _main 
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall DynIntStack<char>::pop(char &)" ([email protected][email protected]@@[email protected]) referenced in function _main 
1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall DynIntStack<char>::push(char)" ([email protected][email protected]@@[email protected]) 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; 
} 

main.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; 
} 

Respuesta

13

Debe colocar todas las implementaciones de plantilla que tenga en su archivo .cpp en el archivo de encabezado o en un archivo incluido en el encabezado. Y no intente compilar el archivo de implementación. Algunos sistemas intentan compilar archivos con un sufijo .cpp. El compilador necesita ver el código para crear instancias de las plantillas.

+1

Si tuviera una libra por cada vez que veo esta pregunta @EdChum – EdChum

+0

o un upvote :-) – juanchopanza

+0

ah, se me adelantó – stijn

3

en la parte inferior de DynIntStack.h, poner

#include <DynIntStack.cpp> 

Lo que pasa es que el compilador no ve el código de implementación de plantilla por lo que no puede emitir cualquier cosa por ella.

-2

La solución más simple al problema es:

todo aquello que desee incluir su clase de plantilla, por ejemplo, "DynIntStack.h" en su lugar hace "DynIntStack.cpp". p.ej. en su main.cpp anterior.

Tan simple como eso, no hay necesidad de cambiar nada más.

Cuestiones relacionadas