Вопрос по undefined-reference, templates, c++ – C ++ неопределенная ссылка на метод класса шаблона [дубликат]

1

На этот вопрос уже есть ответ здесь:

Почему я получаюнеразрешенный внешний символ » ошибки при использовании шаблонов? [Дубликат] 3 ответаНеопределенная ссылка на членов шаблона 1 ответ

Я всегда получаю

неопределенная ссылка на `Graph :: InsertVertex (std :: string) '

если я скомпилирую свой проект! Любые намеки, почему он не может решить эту ссылку? (все файлы находятся в папке проекта netbeans)

//main.cpp

#include 
#include 
#include "Graph.h"

using namespace std;

int main(int argc, char** argv)
{
    Graph *graph = new Graph(); // InsertVertex("A");

    return 0;
}

//node.h

#include 
#include "Graph.h"

template 
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 *vertList;
    Node *next;
    int status;

};

//Graph.h

#include 
#include "Node.h"

template  
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 *head;

};

//Graph.cpp

#include "Graph.h"

template 
void Graph::InsertVertex(T val)
{
    Node *temp = new Node(val);

    if(head == NULL) head = temp;
    else
    {
        Node node = head;

        while(node->vertList != NULL)
            node = node->vertList;

        node->vertList = temp;
    }   
}

template 
void Graph::InsertEdge(T v_val, T e_val)
{
    if (head != NULL)
    {
        Node *k = head;
        Node *t = head;
        Node *temp = new Node (e_val);        

        while (t != NULL)
        {
            if (t->data == v_val)
            {
                Node *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 next != NULL)
            {
                std::cout < t->next->vertList->data < "   ";
                t = t->next;
            }
        }
        t = t->vertList;
    }
}

template 
Это'Спрашивали как минимум пять раз на этой неделе. Вы должны серьезно улучшить свой поиск-дзюцу. :п Simon G.
Что значитfriend class Graph; значит, еслиGraph это неclass, ноtemplate? Google для "C ++ Friend Template " Maciej Hehl
Вы не можете поместить определения функций-членов шаблона класса в.cpp файл. Andy Prowl
Поиск по собственному названию вопроса "C ++ неопределенная ссылка на метод класса шаблона " для объяснений объяснений Drew Dormann

Ваш Ответ

2   ответа
11

чтобы ваши шаблонные методы были в заголовке, чтобы они компилировались при необходимости. Если вы действительно хотите скрыть это в файле реализации, вы должны явно создать экземпляр шаблона вGraph.cpp лайк

template class  Graph<string>;
</string>

Так как вы должны сделать это для каждого типаT вы собираетесь использовать сGraphточка класса шаблона несколько побеждена, и вам лучше поместить все в заголовок

Кажется яЯ не достаточно умен: теперь я добавил определение из cpp в файл заголовка (дополнительное определение или добавьте его в фигурные скобки к объявлению функции). Дайте мне пример для 1 функции, пожалуйста! leon22
смотри мой обновленный ответ emesx
Обратите внимание, что недостаточно создать экземпляр класса, чтобы заставить компилятор генерировать соответствующие методы. Вам нужно использоватьtemplate class ClassName; синтаксис, чтобы заставить его работать должным образом. Вы можете'т просто придерживатьсяClassName instance; и ожидаем, что компилятор решит, что ему нужны все методы (что он должен уметь делать). Возможно, вы захотите сделать это, чтобы компилятор снова и снова генерировал один и тот же объект, когда шаблон класса включен в несколько файлов cpp. Eosis
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;
};
</t></t></t></class>

Похожие вопросы