【问题标题】:C++ undefined reference to template class method [duplicate]C ++未定义对模板类方法的引用[重复]
【发布时间】:2013-02-01 13:47:46
【问题描述】:

我总是得到

对 `Graph::InsertVertex(std::string)' 的未定义引用

如果我编译我的项目!任何提示为什么他不能解决这个参考? (所有文件都在 netbeans 项目文件夹中)

// ma​​in.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;
    }
}

【问题讨论】:

  • 您不能将类模板的成员函数定义放在.cpp 文件中。
  • 本周至少有人问过这个问题五次。你应该认真改进你的搜索术。 :p
  • 搜索你自己的问题标题"C++ undefined reference to template class method" 以获得大量的stackoverflow解释。
  • 如果Graph 不是class,而是template,那么friend class Graph; 是什么意思?谷歌的“C++ 朋友模板”

标签: c++ templates undefined-reference


【解决方案1】:

通常你希望你的模板方法在头文件中,以便在需要时编译它们。如果你真的想在实现文件中隐藏它,你必须在Graph.cpp中显式实例化模板,就像

template class  Graph<string>;

由于您必须对您打算与Graph&lt;T&gt; 一起使用的每种类型T 执行此操作,因此模板类的要点有些失败,您最好将所有内容都放在标题中

【讨论】:

  • 看来我不够聪明:我现在将cpp中的定义添加到头文件中(额外定义或用大括号将其添加到函数声明中)请给我一个函数的例子!
  • 请注意,仅仅实例化一个类的实例来让编译器生成适当的方法是不够的。您需要使用template class ClassName&lt;typename&gt;; 语法才能使其正常工作。您不能只坚持ClassName&lt;typename&gt; instance; 并期望编译器能够计算出它需要所有方法(它应该能够做到)。当类模板包含在多个 cpp 文件中时,您可能希望这样做以阻止编译器一遍又一遍地生成相同的对象。
【解决方案2】:

您需要在头文件中定义成员函数,因为在实例化模板时,编译器需要访问方法的实现,以使用模板参数实例化它们。

在你的例子中:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 2010-11-09
    • 2015-10-12
    • 1970-01-01
    • 2012-05-24
    相关资源
    最近更新 更多