Question

What is the best way of declaring my header files if I want to have the following connections in my C++ code, just so that I don't get the 'include nested too deeply error'?

On my edge class, I have some functions that need to return a Node object. Same for the Edge class, I have functions that need to return a Node object. However the compiler disallow me to have this nested loop thing.

Node.h

#ifndef _NODE_h__
#define __NODE_h__

#include "Edge.h" 
public:
    Node();
    ~Node();
    void setName(string);
    string getName();
    void addEdge(Edge*);
    vector<Edge* > getEdges() { return _edges; };
};
#endif

Edge.h

#ifndef _EDGE_h__
#define __EDGE_h__

#include "Node.h"
class Edge 
{
public:

    Edge();
    Edge(bool);
    ~Edge();
    bool hasBeenSeen() { return _seen; };
    void reset() { _seen = false; };  // resets seen param to false
    Node* getSource() { return _source; };
    Node* getTarget() { return _target; };
    void setSource(Node* source) { _source = source; };
    void setTarget(Node* target) { _target = target; };
};
#endif
Was it helpful?

Solution

As others have suggested, use header guards. But also try forward declaring the classes in question. You may also have to work with pointers (rather than values) in at least one of your classes, but without seeing the code, we can't tell.

So edge.h should like something like:

#ifndef EDGE_H
#define EDGE_H

class Node;    // forward declaration

Node functionB();

#endif

Note that you will have to define your function in a separate C++ file which then #includes "node.h".

If all this seems very complicated, then you should try simplifying your design. It is probably not necessary for nodes and edges to know about each other — a one way dependency should suffice.

And lastly, names containing double-underscores are reserved in C++ — you are not allowed to create such names in your own code.

OTHER TIPS

Edge.h

#ifndef EDGE_H_INCLUDED
#define EDGE_H_INCLUDED

class Node;

class Edge
{
    int edge_num;
public:
    Edge(int i) : edge_num(i) { };
    Node memberB();
};

#include "Node.h"  

Node Edge::memberB() { Node n(edge_num); return n; }
Node functionB()     { Node n(2);        return n; }

#endif /* EDGE_H_INCLUDED */

Node.h

#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED

class Edge;

class Node
{
    int node_num;
public:
    Node(int i) : node_num(i) { };
    Edge memberA();
};

#include "Edge.h"

Edge Node::memberA() { Edge e(node_num); return e; }
Edge functionA()     { Edge e(1);        return e; }

#endif /* NODE_H_INCLUDED */

Note that I have forward declared the classes 'Edge' and 'Node' before the other header is included, so that by the time the function or member function is defined, the class it returns is also defined.

The problem with your include guards is that they don't match!

You test for _SOMETHING (one underscore) and then if not found you define __SOMETHING (two underscores); these two should match else the include guard does not work!

As others have noted avoid starting things with underscores as those are reserved for libs and OS.

This is prevented by using either pragma guards or #pragma once (the latter if your compiler supports it).

To use pragma guards, simply do this:

#ifndef SOME_IDENTIFIER
#define SOME_IDENTIFIER

// ... code ...

#endif

Make sure to change SOME_IDENTIFIER for every header file. Usually people make it NAME_OF_HEADER_H; make sure you change both instances of the identifier if you change one.

Also if you do this, make sure any #includes you do are inside the pragma guards.

If you just want to use #pragma once and your compiler supports it, you just have to add

#pragma once

to the top of your header file.

On another note, consider moving the definition of the functions functionA and functionB to their own .cpp files and keeping just the prototype in the .h files, so you don't get linker errors.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top