我总是得到
未定义对`Graph :: InsertVertex(std :: string)'
的引用
如果我编译我的项目!有什么提示他为什么不能解决这个问题? (所有文件都在netbeans项目文件夹中)
// main.cpp
#include <cstdlib>
#include <string>
#include "Graph.h"
using namespace std;
int main(int argc, char** argv)
{
Graph<string> *graph = new Graph<string>(); // <--- ERROR
graph->InsertVertex("A");
return 0;
}
// Node.h
#include <iostream>
#include "Graph.h"
template<class T>
class Node
{
friend class Graph;
public:
Node(T val)
{
this->data = val;
this->vertList = NULL;
this->next = NULL;
}
Node(const Node& orig);
virtual ~Node();
private:
T data;
Node<T> *vertList;
Node<T> *next;
int status;
};
// Graph.h
#include <iostream>
#include "Node.h"
template <class T>
class Graph
{
public:
Graph()
{
head = NULL;
}
void InsertVertex(T val);
void InsertEdge(T v_val, T e_val);
void PrintVertices();
void PrintEdges(T v_val);
void DeleteEdge(T v_val, T e_val);
void DeleteVertex(T val);
void bfs();
private:
Node<T> *head;
};
// Graph.cpp
#include "Graph.h"
template <class T>
void Graph<T>::InsertVertex(T val)
{
Node<T> *temp = new Node<T>(val);
if(head == NULL) head = temp;
else
{
Node<T> node = head;
while(node->vertList != NULL)
node = node->vertList;
node->vertList = temp;
}
}
template <class T>
void Graph<T>::InsertEdge(T v_val, T e_val)
{
if (head != NULL)
{
Node<T> *k = head;
Node<T> *t = head;
Node<T> *temp = new Node<T> (e_val);
while (t != NULL)
{
if (t->data == v_val)
{
Node<T> *s = t;
while (s->next != NULL)
s = s->next;
s->next = temp;
while (k != NULL)
{
if(k->data == e_val) break;
k = k->vertList;
}
temp->vertList = k;
return;
}
t = t->vertList;
} // end while loop
}
else std::cout << "Add first vertices to the graph" << std::endl;
}
template <class T>
void Graph<T>::PrintEdges(T v_val)
{
Node<T>* t = head;
while (t != NULL)
{
if (t->data == v_val)
{
while (t->next != NULL)
{
std::cout << t->next->vertList->data << " ";
t = t->next;
}
}
t = t->vertList;
}
}
template <class T>
void Graph<T>::PrintVertices()
{
Node<T>* t = head;
while (t != NULL)
{
std::cout << t->data << " ";
t = t->vertList;
}
}
答案 0 :(得分:11)
通常,您希望在标头中使用模板方法,以便在需要时进行编译。如果你真的想在实现文件中隐藏它,你必须在Graph.cpp
中显式实例化模板,如
template class Graph<string>;
由于你必须为你想要与T
一起使用的每种类型Graph<T>
执行此操作,因此模板类的要点有些失败,你最好将所有内容放入标题中
答案 1 :(得分:7)
您需要在头文件中定义成员函数,因为在实例化模板时,编译器需要能够访问方法的实现,并使用模板参数对它们进行实例化。
在你的例子中:
template <class T>
class Graph {
public:
void InsertVertex(T val) {
Node<T> *temp = new Node<T>(val);
if(head == NULL)
head = temp;
// ...
}
// ...
private:
Node<T> *head;
};