0

I'm writing some templated data structures for future use and have a class Node that appears in both my singly linked list and graph implementations. Each of these headers have header guards, but I'm still getting an error of redefinition:

In file included from driver.cc:4:
./Graph.h:7:7: error: redefinition of 'Node'
class Node {
      ^
./SinglyLinkedList.h:5:7: note: previous definition is here
class Node {
      ^
1 error generated.

SinglyLinkedList.h

#ifndef SINGLY_LINKEDLIST_H
#define SINGLY_LINKEDLIST_H

template <class T>
class Node {
    public:
        Node<T>() {} 
        Node<T>(T init) { data = init; }

        void setData(T newData) { data = newData; }
        void setNext(Node<T> *nextNode) { next = nextNode; }

        const T getData() { return data; }
        const Node<T> *getNext() { return next; }
    private:
        T data;
        Node<T> *next;
};

template <class T>
class SLL {
    public:
        SLL<T>() { head = NULL; }
    private:
        Node<T> *head;
};

#endif

Graph.h

#ifndef GRAPH_H
#define GRAPH_H

#include <vector>

template <class T>
class Node {
    public:
        Node<T>() {};
        Node<T>(T init) { data = init; }
    private:
        T data;
};

template <class T>
class Edge {
    public:
        Edge<T>(Node<T> a, Node<T> b);
    private:
        Node<T> to;
        Node<T> from;
};

template <class T>
class Graph {
    public:
        Graph<T>(bool direction) { directed = direction; }
        const bool getDirection() { return directed; }
    private:
        std::vector<Edge<T> > adjList;
        bool directed; 
};

#endif

driver.cc

#include <iostream>
#include <string>
#include "SinglyLinkedList.h"
#include "Graph.h"

int main() 
{
    Graph<int> Hello(false);

    return 0;
}

I know the classes are not complete and I know there's no need to reinvent the wheel because everything I'll ever need exists in std, but can someone explain why there's a redefinition error of the class Node?

My assumption is that the compiler doesn't see a definition of SINGLY_LINKEDLIST_H, so it creates a definition for everything in its class; then it again doesn't see GRAPH_H and attempts to create a definition for everything in the Graph class which yields an error.

If this is so, how should I proceed? Create a separate Node class? Make a Node header which has things that might be needed for both data structures?

Just looking for tips.

Thanks, erip

erip
  • 16,374
  • 11
  • 66
  • 121
  • 6
    Node is defined twice. Both headers have a different definition for it! You could put the Node class definition inside the SLL class. Then it would not need to be templated either since it would just use T from the SLL class' template. – qeadz Mar 23 '15 at 18:49
  • 2
    [One definition rule](http://stackoverflow.com/q/4192170/3425536)!! – Emil Laine Mar 23 '15 at 18:51
  • 1
    Since there is no `namespace`, the names *clash*. You can't do this. Wrap in a namespace, rename, or nest the definitions within the class that uses them (or, make them the same and only have *one* declaration/definition). – crashmstr Mar 23 '15 at 18:51
  • 1
    Why are there downvotes for this question? I gave my code and explained what I thought was happening... I'm not asking anything unreasonable. – erip Mar 23 '15 at 18:53
  • @erip was not me, but this has nothing to do with header include guards, for one thing (since you *do* intentionally redefine the class). – crashmstr Mar 23 '15 at 18:54
  • 1
    @erip Even if you were to have the exact same definition for Node - copy/pasted - it would still complain. You may only define the details for it *once*. Every other mention may only be a forward declaration. – qeadz Mar 23 '15 at 18:54
  • @erip Probably because of "this question does not show any research effort". A simple search for "two definitions of class" or similar would have probably answered your question. Btw downvote not mine. – Emil Laine Mar 23 '15 at 18:55
  • [My research effort](https://www.google.com/search?q=error%3A+redefinition+of+c%2B%2B&oq=error%3A+redefinition+of+c%2B%2B&aqs=chrome..69i57j69i58j69i60.1395j0j4&sourceid=chrome&es_sm=91&ie=UTF-8#q=error:+redefinition+of+class+c%2B%2B) showed a lot of header guard problems. People are too quick to downvote without constructive feedback. – erip Mar 23 '15 at 18:59
  • @erip: Don't take the downvotes personally. Some people downvote questions they see as "too elementary for SO", and this question might be viewed as such. – John Dibling Mar 23 '15 at 19:06

1 Answers1

3

You need to either:

  • Factor Node class into separate header file.
  • Or Rename the Node class to differentiate.
  • Put Node classes into separate namespaces.

As demonstrated in your question, both header files contain a definition of a Node class, and you have confused the compiler.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154