2017-04-03 2 views
0

벡터, 목록 및 동적 배열을 사용하여 자체 스택 및 대기열을 만듭니다. 내 프로그램을 컴파일 할 때 3 개의 링크 오류가 발생합니다.

나는이 내 스택과 큐에 대한 다음 헤더 파일 :

miniStack.h

#ifndef MINISTACK_H 
#define MINISTACK_H 

#include <vector> 
#include <list> 

using namespace std; 

template <typename T> 
class miniStackVT { 
private: 
    vector<T> content; 
    int elementCount; 
public: 
    miniStackVT(); 
    ~miniStackVT(); 
    int size() const; 
    bool IsEmpty() const; 
    void Push(const T& item); 
    void PrintStack(); 
    void Pop(); 
    T& TopStack(); 
}; 

template <typename T> 
class miniStackLT { 
private: 
    list<T> content; 
    int elementCount; 
public: 
    miniStackLT(); 
    ~miniStackLT(); 
    int size() const; 
    bool IsEmpty() const; 
    void Push(const T& item); 
    void PrintStack(); 
    void Pop(); 
    T& TopStack(); 
}; 

template <typename T> 
class miniStackDA { 
private: 
    T* content; 
    int elementCount; 
    void reserve(int n, bool copy); 
    int arrSize; 
public: 
    miniStackDA(); 
    ~miniStackDA(); 
    int size(); 
    bool IsEmpty(); 
    void Push(const T& item); 
    void PrintStack(); 
    void Pop(); 
    T& TopStack(); 
}; 

#endif 

miniQueue.h 여기

#ifndef MINIQUEUE_H 
#define MINIQUEUE_H 

#include <vector> 
#include <list> 

using namespace std; 

template <typename T> 
class miniQueueVT { 
private: 
    vector<T> content; 
    int elementCount; 
public: 
    miniQueueVT(); 
    ~miniQueueVT(); 
    void enqueue(const T&); 
    void dequeue(); 
    T& front(); 
    void PrintQueue() const; 
    bool IsEmpty(); 
    int size(); 
}; 

template <typename T> 
class miniQueueLT { 
private: 
    list<T> content; 
    int elementCount; 
public: 
    miniQueueLT(); 
    ~miniQueueLT(); 
    void enqueue(const T&); 
    void dequeue(); 
    T& front(); 
    void PrintQueue(); 
    bool IsEmpty(); 
    int size(); 
}; 

template <typename T> 
class miniQueueDA { 
private: 
    T *content; 
    int elementCount; 
    void reserve(int n, bool copy); 
    int arrSize; 
public: 
    miniQueueDA(); 
    ~miniQueueDA(); 
    void enqueue(const T&); 
    void dequeue(); 
    T& front(); 
    void PrintQueue(); 
    bool IsEmpty(); 
    int size(); 
}; 

#endif 

내 .CPP 파일은 내 헤더 파일과 관련 :

miniStack.cpp :

#include "miniStack.h" 
#include <vector> 
#include <list> 
#include <iostream> 


//VECTOR MEMBER FUNCTIONS 
template <typename T> 
miniStackVT<T>::miniStackVT() { 
    elementCount = 0; 
    content.resize(0); 
} 


template <typename T> 
int miniStackVT<T>::size() const{ 
    return content.size(); 
} 

template <typename T> 
bool miniStackVT<T>::IsEmpty() const{ 
    return content.empty(); 
} 

template <typename T> 
void miniStackVT<T>::Push(const T& item) { 
    content.push_back(item); 
    elementCount++; 
} 

template <typename T> 
void miniStackVT<T>::PrintStack() { 
    for(int i = elementCount - 1; i >= 0; i--) { 
     cout << content[i] << " | "; 
    } 
} 

template <typename T> 
void miniStackVT<T>::Pop() { 
    content.pop_back(); 
    elementCount--; 
} 

template <typename T> 
T& miniStackVT<T>::TopStack() { 
    return content.back(); 
} 

//LIST MEMBER FUNCTIONS 
template <typename T> 
miniStackLT<T>::miniStackLT() { 
    elementCount = 0; 
    content.resize(0); 
} 

template <typename T> 
miniStackLT<T>::~miniStackLT() { 

} 

template <typename T> 
int miniStackLT<T>::size() const{ 
    return content.size(); 
} 

template <typename T> 
bool miniStackLT<T>::IsEmpty() const{ 
    return content.empty(); 
} 

template <typename T> 
void miniStackLT<T>::Push(const T& item) { 
    content.push_back(item); 
    elementCount++; 
} 

template <typename T> 
void miniStackLT<T>::PrintStack() { 
    list<T>::iterator rit; 
    for (auto rit = content.rbegin(); rit != content.rend(); ++rit) { 
     cout << *rit << " | "; 
    } 
} 

template <typename T> 
void miniStackLT<T>::Pop() { 
    content.pop_back(); 
    elementCount--; 
} 


//DARRAY DATA MEMBERS 
template <typename T> 
miniStackDA<T>::miniStackDA() { 
    arrSize = 50; 
    content = new T[arrSize]; 
    elementCount = 0; 
} 

template <typename T> 
miniStackDA<T>::~miniStackDA() { 
    delete[] content; 
} 

template <typename T> 
int miniStackDA<T>::size() { 
    return elementCount; 
} 

template <typename T> 
bool miniStackDA<T>::IsEmpty() { 
    if (elementCount == 0) 
     return true; 
    else return false; 
} 

template <typename T> 
void miniStackDA<T>::Push(const T& item) { 
    if (elementCount < arrSize) { 
     content[elementCount] = item; 
     elementCount++; 
    } 
    else { 
     reserve(arrSize * 2, true); 
     content[elementCount] = item; 
     elementCount++; 
    } 
} 

template <typename T> 
void miniStackDA<T>::reserve(int n, bool copy) { 
    T *newArr; 
    int i; 

    newArr = new T[n]; 

    if (copy) 
     for (i = 0; i < elementCount; i++) 
      newArr[i] = content[i]; 

    if (content != NULL) 
     delete[] content; 

    content = newArr; 
    elementCount = n; 
} 

template <typename T> 
void miniStackDA<T>::PrintStack() { 
    for (int i = elementCount - 1; i >= 0; i--) { 
     cout << content[i] << " | "; 
    } 
} 

template <typename T> 
void miniStackDA<T>::Pop() { 
    elementCount--; 
} 

template <typename T> 
T& miniStackDA<T>::TopStack() { 
    return content[elementCount - 1]; 
} 

miniQueue.cpp :

#include "miniQueue.h" 
#include "iostream" 
#include <vector> 
#include <list> 

using namespace std; 

//START VECTOR MEMBER FUNCTIONS 

template <typename T> 
miniQueueVT<T>::miniQueueVT() { 
    elementCount = 0; 
    content.resize(0); 
} 

template <typename T> 
miniQueueVT<T>::~miniQueueVT() { 

} 

template <typename T> 
void miniQueueVT<T>::enqueue(const T& item) { 
    content.push_back(item); 
    elementCount++; 
} 

template <typename T> 
void miniQueueVT<T>::dequeue() { 
    content.pop_back(); 
    elementCount--; 
} 

template <typename T> 
T& miniQueueVT<T>::front() { 
    return content.front(); 
} 

template <typename T> 
void miniQueueVT<T>::PrintQueue() const { 
    for (int i = elementCount - 1; i >= 0; i--) { 
     cout << content[i] << " | "; 
    } 
} 

template <typename T> 
bool miniQueueVT<T>::IsEmpty() { 
    return content.empty(); 
} 

template <typename T> 
int miniQueueVT<T>::size() { 
    return elementCount; 
} 

//START LIST MEMBER FUNCTIONS 

template <typename T> 
miniQueueLT<T>::miniQueueLT() { 
    elementCount = 0; 
    content.resize(0); 
} 

template <typename T> 
miniQueueLT<T>::~miniQueueLT() { 

} 

template <typename T> 
void miniQueueLT<T>::enqueue(const T& item) { 
    content.push_back(item); 
    elementCount++; 
} 


template <typename T> 
void miniQueueLT<T>::dequeue() { 
    content.pop_front(); 
    elementCount--; 
} 

template <typename T> 
T& miniQueueLT<T>::front() { 
    return content.front(); 
} 

template <typename T> 
void miniQueueLT<T>::PrintQueue() { 
    list<T>::iterator iter; 
    for (iter = content.begin(); iter != content.end(); iter++) { 
     cout << *iter << " | "; 
    } 
} 

template <typename T> 
bool miniQueueLT<T>::IsEmpty() { 
    return content.empty(); 
} 

template <typename T> 
int miniQueueLT<T>::size() { 
    return content.size(); 
} 


//START DYNAMIC ARRAY MEMBER FUNCTIONS 

template <typename T> 
miniQueueDA<T>::miniQueueDA() { 
    arrSize = 50; 
    content = new T[arrSize]; 
    elementCount = 0; 
} 

template <typename T> 
miniQueueDA<T>::~miniQueueDA() { 

} 

template <typename T> 
void miniQueueDA<T>::enqueue(const T& item) { 
    if (elementCount < arrSize) { 
     content[elementCount] = item; 
    } 
    else { 
     reserve(arrSize * 2, true); 
     content[elementCount] = item; 
     elementCount++; 
    } 
} 


template <typename T> 
void miniQueueDA<T>::dequeue() { 
    elementCount--; 
} 

template <typename T> 
void miniQueueDA<T>::reserve(int n, bool copy) { 
    T *newArr; 
    int i; 

    newArr = new T[n]; 

    if (copy) { 
     for (i = 0; i < elementCount; i++) { 
      newArr[i] = content[i]; 
     } 
    } 
    if (content != NULL) 
     delete[] content; 

    content = newArr; 
    elementCount = n; 
} 


template <typename T> 
T& miniQueueDA<T>::front() { 
    return content[0]; 
} 

template <typename T> 
bool miniQueueDA<T>::IsEmpty() { 
    if (elementCount == 0) 
     return true; 
    else return false; 
} 

template <typename T> 
int miniQueueDA<T>::size() { 
    return elementCount; 
} 
template <typename T> 
void miniQueueDA<T>::PrintQueue() { 
    for (int i = elementCount - 1; i >= 0; i--) { 
     cout << content[i] << " | "; 
    } 
} 

내가 프로그램 컴파일 갈 때 나는 다음과 같은 오류가 받고 있어요 :

Error LNK2019 unresolved external symbol "public: __thiscall miniStackVT<int>::~miniStackVT<int>(void)" ([email protected]@@[email protected]) referenced in function "void __cdecl StackVTMenu<int>(class miniStackVT<int>)" ([email protected]@@[email protected]@@@Z) Project 2 E:\Project 2\Project 2\Driver.obj 1 
Error LNK2019 unresolved external symbol "public: int & __thiscall miniStackLT<int>::TopStack(void)" ([email protected][email protected]@@QAEAAHXZ) referenced in function "void __cdecl StackLTMenu<int>(class miniStackLT<int>)" ([email protected]@@[email protected]@@@Z) Project 2 E:\Project 2\Project 2\Driver.obj 1 
Error LNK1120 2 unresolved externals Project 2 E:\Project 2\Debug\Project 2.exe 1 

을 주 파일과 .h 파일에 어떤 파일이 포함되어 있는지를 변경하려고했습니다. 지금은 miniStack.cppminiQueue.cpp이 메인에 포함되어 있습니다.

도움을 주시면 감사하겠습니다.

답변

0

C++에서 템플릿을 사용하는 경우 헤더 파일에 구현이 있어야합니다. 소스 파일에만 구현하면 컴파일러는 각 파일을 컴파일하고 나중에 링크합니다.

그러나 컴파일러는 구체적인 사용법을 검사하여 제네릭 형식을 관찰해야하므로 템플릿의 경우에는 작동하지 않습니다.

+0

그래서 내 구현을 모두 내 2 헤더 파일에 넣어야합니까? –

+0

모두 필요한 경우에 따라 다릅니다. 제네릭 형식 T가 구체적인 사용법을 가지고 있고 컴파일러가 T를 구체적인 형식으로 바꾸려면이를 관찰해야하는 모든 것을 포함하십시오. 편집 : 포함하여 전 헤더에 넣어, 전처리 기 '# include' 컨텍스트에 포함하지 마십시오. – datell

+0

몇 가지 시도해보십시오. –