【问题标题】:Getting 3 link errors when trying to compile my program [duplicate]尝试编译我的程序时出现 3 个链接错误 [重复]
【发布时间】:2017-04-03 15:43:18
【问题描述】:

我正在使用向量、列表和动态数组创建自己的堆栈和队列。

我的堆栈和队列有以下头文件:

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)" (??1?$miniStackVT@H@@QAE@XZ) referenced in function "void __cdecl StackVTMenu<int>(class miniStackVT<int>)" (??$StackVTMenu@H@@YAXV?$miniStackVT@H@@@Z)    Project 2   E:\Project 2\Project 2\Driver.obj   1
Error   LNK2019 unresolved external symbol "public: int & __thiscall miniStackLT<int>::TopStack(void)" (?TopStack@?$miniStackLT@H@@QAEAAHXZ) referenced in function "void __cdecl StackLTMenu<int>(class miniStackLT<int>)" (??$StackLTMenu@H@@YAXV?$miniStackLT@H@@@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 包含在主目录中。

任何帮助将不胜感激。

【问题讨论】:

    标签: c++ class stack queue


    【解决方案1】:

    如果您在 C++ 中使用模板,您的头文件必须包含实现。如果您只在源文件中实现,编译器将编译每个文件并稍后链接。

    但这不适用于模板,因为编译器必须通过检查其具体用法来观察泛型类型。

    【讨论】:

    • 所以我应该把我所有的实现放在我的 2 个头文件中?
    • 这取决于您是否需要所有这些。包括泛型类型 T 具有具体用法的所有内容,并且编译器必须观察它以将 T 替换为具体类型。编辑:我的意思是包含在你的标题中,而不是包含在预处理器#include上下文中
    • 过会儿试试
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    相关资源
    最近更新 更多