I have a node class which gives me the following compiler error on a simple header declaration. I really cannot see why its being caused?!
1> Node.h(4): error : invalid redeclaration of type name "Node" (declared at line 4)
1> class Node{
1> ^
Header:
using namespace std;
class Node{ //THIS IS LINE 4
public:
Node(int val);
int val;
Node* l_node;
Node* r_node;
private:
};
Source:
#include "Node.h"
Node::Node(int x) : l_node(nullptr), r_node(nullptr), val(x){
}
Do I need a forward declaration or something???
When you write a header file, always remember to write an include guard.
#ifndef NODE_H
#define NODE_H
class Node{
public:
explicit Node(int val); // add explicit to disable implicit conversion
int val;
Node* l_node;
Node* r_node;
};
#endif
Also, do NOT use using directives in header file; it's bad practice.
And in constructors, beware of member initialization order. Initialize members in declaration order, otherwise you might get caught by an initialize order issue:
Node::Node(int x) : val(x), l_node(nullptr), r_node(nullptr){
}
Aside from include guards, you should almost always create a corresponding .cpp file for every header, and put the implementation there. If you have multiple libs using the same header, and they get linked in together by a third program, it will produce linker errors. Include guards won't protect you against this scenario.
Related
in my header file for my HuffmanTree binary tree class I have the declaration of my destructor:
//huffman.h
using namespace std;
#ifndef HuffmanTree_H
#define HuffmanTree_H
class HuffmanTree
{
public:
~HuffmanTree();
};
#endif
and in my cpp file I have the implementation of my destructor
//huffman.cpp
#include "huffman.h"
using namespace std;
//destructor
HuffmanTree::~HuffmanTree()
{
}
note: I have not finished writing the destructor body because I want it to compile
the exact text of the error is:
huffman.cpp:8:27: error: definition of implicitly-declared ‘HuffmanTree::~HuffmanTree()’
HuffmanTree::~HuffmanTree()
^
thank you for any help you can give
In your header add this:
class HuffmanTree {
public:
~HuffmanTree(void);
In your .cpp file:
HuffmanTree::~HuffmanTree(void) {
;
}
Adding 'void' worked for me.
I'm trying to adapt a bit of code for a doubly-linked list to be included and used in my mysh.cpp file, and I'm getting
error: aggregate ‘linked_list list’ has incomplete type and cannot be defined
on compile. readcommand.cpp compiles just fine, so I'm just trying to figure out what needs to be changed either in the header file or cpp files to get it running smoothly for mysh.
Here are the relevant portions of the files used:
mysh.cpp
#include "readcommand.h"
using namespace std;
int main (int argc, char** argv) {
readcommand read;
linked_list list; // THIS is the line that's causing the error
...
}
readcommand.h
#ifndef READCOMMAND_H
#define READCOMMAND_H
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
class readcommand {
public:
// Struct Definitions
typedef struct node node_t;
typedef struct linked_list linked_list_t;
struct node;
struct linked_list;
...
};
#endif
readcommand.cpp
#include "readcommand.h"
using namespace std;
struct node {
const char *word;
node *prev;
node *next;
};
struct linked_list {
node *first;
node *last;
};
...
It's been a while since I've used headers in c++, or the language in general. I've tried changing the line in question to
read.linked_list list;
and
read.linked_list list = new linked_list;
and the like, but it just changes the error to things like
error: ‘class readcommand’ has no member named ‘linked_list’
and
error: invalid use of ‘struct readcommand::linked_list’
Thanks ahead of time.
You need to put these...
struct node {
const char *word;
node *prev;
node *next;
};
struct linked_list {
node *first;
node *last;
};
...someplace where the compiler will see them before they are used in class readcommand. Probably the easiest thing to do would be to put them in readcommand.h before class readcommand. The problem is that node and linked_list are being used in your class readcommand but the compiler doesn't know what they are at that point in the compilation.
The struct/class definition (and not just declaration) needs to be visible when you
dereference a pointer to that struct/class
create an object of that struct/class
The compiler needs to know the size of the object and the location of its fields.
That is why you may want to put the definitions of node and linked_list into the .h file.
Typically, you put into .cpp only the definitions of member functions.
You have the definition of linked_list in the cpp file... so if you include the .h file, the compiler doesn't see that struct's definition.
Move the struct's definition to the header file.
In readcommend.h
linked_list is a member of class readcommand, you can access it through readcommand object or move linked_list to readcommand.h insead if readcommand.cpp so compiler know "what is it"
I'm having trouble with compiling my template class. This is my list.cpp
using namespace std;
template <class T>
List<T>::List()
{
length = 0;
}
template <class T>
List<T>::~List()
{
}
template <class T>
List<T> & List<T>::operator=(const List<T> & rhs)
{
List<T> hha;
return hha;
}
template <class T>
int List<T>::size()
{
return length;
}
ANd this is my list.h
#ifndef _LIST_H_
#define _LIST_H_
#include <iterator>
#include <ostream>
using namespace std;
template <class T>
class List
{
private:
class ListNode
{
public:
ListNode();
ListNode(const T element);
ListNode *next;
T data;
};
public:
// big3
List();
~List();
List<T> & operator=(const List<T> & rhs);
int size();
bool empty();
void print(ostream & os) const;
private:
ListNode * head;
ListNode * tail;
int length;
};
#include "list.cpp"
#endif
when I run g++ list.cpp
I get errors
expected constructor, destructor, or type conversion before ‘<’ token
for definitions of constructor, destructor, and operator...
I don't know what seems to be wrong
The template implementation goes in the header.
It is a bit of a hack but it is how it is done.
The problem you currently encounter is that you list.cpp doesn't include you list.h: the compiler sees a couple of definitions for things which aren't declared, yet. You can fix this problem by including list.h at the top of your file:
#include "list.h"
...
However, this will essentially lead to a problem coming: if you actually want to use your List<T> with some type, the compiler will need to see the template definition where the class template is used. That is, typically you will implement your templates in the header file. The alterntaive is to implement templates in an implementation file and explicitly instantiating the types it is to be used with. This is quite reasonable for some templates but for something intended to be used for an unknown number of types this isn't practical.
BTW, you are using names which you are not allowed to touch: names starting with an underscore followed by a capital letter are reserved for the C++ implementation, i.e. the compiler and the standard library. Names using two consecutive underscores anywhere are also reserved.
Since list.hpp doesn't get #included in list.cpp, the compiler doesn't know about the template definition in that header when you try to compile list.cpp.
You compile list.cpp, that defines your list member functions. But it doesn't contain the template class declaration - that is in the header.
I see you include cpp in your list header. This will sort of work if you include the list header in some other cpp file and make sure list.cpp will not be compiled as a separate compilation unit.
What I mean is i.e. file main.cpp:
#include "list.h"
int main()
{}
Then compile this with g++ main.cpp.
Usually you just want to avoid cpp files when using templates altogether. Just stuff everything in the header and include that. Or alternatively I would at least rename your list.cpp to list.impl or some other name. This way one might be less tempted to actually try to compile that file directly.
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
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.
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.
I'm experiencing some problems with breaking my code to reusable parts using templates and inheritance. I'd like to achieve that my tree class and avltree class use the same node class and that avltree class inherits some methods from the tree class and adds some specific ones. So I came up with the code below. Compiler throws an error in tree.h as marked below and I don't really know how to overcome this. Any help appreciated! :)
node.h:
#ifndef NODE_H
#define NODE_H
#include "tree.h"
template <class T>
class node
{
T data;
...
node()
...
friend class tree<T>;
};
#endif
tree.h
#ifndef DREVO_H
#define DREVO_H
#include "node.h"
template <class T>
class tree
{
public: //signatures
tree();
...
void insert(const T&);
private:
node<T> *root; //missing type specifier - int assumed. Note: C++ does not support default-int
};
//implementations
#endif
avl.h
#ifndef AVL_H
#define AVL_H
#include "tree.h"
#include "node.h"
template <class T>
class avl: public tree<T>
{
public: //specific
int findMin() const;
...
protected:
void rotateLeft(node<T> *)const;
private:
node<T> *root;
};
#endif
avl.cpp (I tried separating headers from implementation, it worked before I started to combine avl code with tree code)
#include "drevo"
#include "avl.h"
#include "vozlisce.h"
template class avl<int>; //I know that only avl with int can be used like this, but currently this is doesn't matter :)
//implementations
...
Both tree.h and node.h try to include each other, the include guards will prevent one of them from seeing the other.
Instead of #include "tree.h" try forward declaring tree like:
template <class T>
class tree;
in node.h
EDIT: As sbi suggested in a comment, it makes more sense to forward declare tree in node.h than the other way around, since it's about granting tree access to node through a friend declaration.
Don't #include "tree.h" in "node.h".
Also, you've declared root in both the tree and avl classes. Qualify tree::root as protected and remove avl::root.
Your problem is that tree.h includes node.h and vice versa. I would not have thought it is necessary (or makes much sense) for the node to have to know about the tree or to grant it friendship, so I'd remove that.
The problem is because of the circular dependency of header files between tree.h and node.h . Since node.h includes tree.h, while compiling the tree class, compiler doesn't know what is the type of node. Since you are using it just for declaring a friend there is no need to include the header file tree.h in node.h