This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 8 years ago.
I have two classes Node and Wire. I am getting an error for the line vector<Wire*> inputs;
Node.h
#ifndef NODE_H_
#define NODE_H_
#include "wire.h"
class Node{
private:
bool sorted;
TGate gateType;
string name;
vector<Wire*> inputs;
vector<Wire*> outputs;
int state;
}
#endif /* NODE_H_ */
Wire.h
#ifndef WIRE_H_
#define WIRE_H_
#include "Node.h"
class Node;
class Wire{
private:
Node* input;
Node* output;
public:
Wire(Node* a, Node* b);
//void setInput(Node* in);
//void setOutput(Node* out);
Node* getInput();
Node* getOutput();
};
#endif /* WIRE_H_ */
wire.cpp
#include "wire.h"
#include"node.h"
class Node;
Wire::Wire(Node* a, Node* b)
{
}
node.cpp
Node::Node(TGate gT, string name)
{
std::cout<<"\nNode created is: "<<name<<"\n";
}
ERROR: /src/node.h:29:9: error: ‘Wire’ was not declared in this scope
In the headers, replace
#include "Node.h"
with
class Node;
and the same for wire.
You have mutually including #includes, so "wire.h" has to include "Node.h" which has to include "wire.h", which has to include.... You need to break this chain, and to do that you use forward declarations.
The compiler needs to know that Node and Wire are classes. Since the #include files only refer to pointers to the other class, the compiler doesn't need to know the class layouts. This removes the mutual dependency and means the compiler can read all the code.
You also should have include guards, to prevent your headers from being compiled twice and causing redefinitions. Some compilers allow #pragma once, and all can handle something like
#ifndef MY_WIRE_H
#define MY_WIRE_H
...
#endif
One stylistic note: you've got Node and Wire, but "Node.h" and "wire.h". It will be easier to keep track of your files if they're consistently capitalized.
Related
I have a simple c++ app:
node.h:
#include<iostream>
using namespace::std;
class Node
{
private:
int data;
Node *next;
public:
Node(int nodeData,Node *nextNode);
};
node.cpp:
#include "node.h"
Node::Node(int nodeData, Node *nextNode) {
data = nodeData;
next = nextNode;
}
linked_list.h
#include "node.h"
class LinkedList
{
private:
Node *head;
Node *tail;
int size;
public:
LinkedList();
int getSize();
};
linked_list.cpp:
#include "linked_list.h"
LinkedList::LinkedList()
{
size = 0;
}
int LinkedList::getSize() {
return size;
}
main.cpp:
#include <iostream>
#include "node.h"
#include "linked_list.h"
using namespace ::std;
int main()
{
cout << "This is main!\n";
return 0;
}
I am on linux, inside the projcet's directory, I open a terminal there and try to compile them by this command:
g++ *.cpp *.h -o app
but I get this error:
In file included from linked_list.h:1:0,
from main.cpp:3:
node.h:1:7: error: redefinition of ‘class Node’
class Node
^~~~
In file included from main.cpp:2:0:
node.h:1:7: note: previous definition of ‘class Node’
class Node
^~~~
I looked at some posts here on stackoverlfow but had no luck in solving my problem. I am new to c++, I know that the compiler thinks I am redefining class Node somewhere, but where is this somewhere so I can remove the definition?
Your linked_list.h includes node.h, so the compiler will see the definition in node.h twice while compiling main.cpp.
To avoid this problem, you should add "include guard" to your header files.
It should be like this:
node.h:
#ifndef NODE_H_GUARD // add this
#define NODE_H_GUARD // add this
#include<iostream>
using namespace::std;
class Node
{
private:
int data;
Node *next;
public:
Node(int nodeData,Node *nextNode);
};
#endif // add this
The macro name to define and check should be different for each headers.
Another way to avoid this problem is to adding #pragma once as the first lines of your headers if your compiler supports this.
My class is not being defined correctly. What do I need to change to make it work? My ExpTree will not work at all, when I go to the implementation file it will not compile, and will give me an error for my class, constructor and destructor. It says that ExpTree is an anonymous struct.
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#ifndef ExpTree
#define ExpTree
using namespace std;
class ExpTree{
public:
ExpTree() {root = NULL;}
~ExpTree();
void build (istream& in_s);
void prefix (ostream& out_s);
void infix(ostream& out_s);
void postfix(ostream& out_s);
int value();
private:
struct Node
{
int operand;
char optr;
Node *left;
Node *right;
};
Node *root;
void destroy(Node* root);
Node* help_build (istream& in_s);
void print_prefix(ostream& out_s, Node* r);
void print_infix(ostream& out_s, Node *r);
void print_postfix(ostream& out_s, Node *r);
int find_value(Node *r);
};
#endif
Don't use the same name for your #define include guard and anything else.
#define ExpTree tells the "preprocessor" to "learn that ExpTree means an empty piece of source code". This does have the desired effect that if the header gets included additional times, the contents will be skipped since the #ifndef will notice that the preprocessor already knows a meaning of ExpTree.
But, with the ExtTree name being used this way, it has the undesired effect that every time ExpTree appears later in your code, it gets replaced with empty code! So the "compiler" sees code like this:
class {
public:
() {root = NULL;}
~ ();
// ...
Which yes, will produce tons of errors.
There are a number of common patterns for include guards, like #define PROJECTNAME_EXPTREE_H. You want to try to reduce the chance it will ever be the same as a name some other code uses.
P.S. It's common practice to put #include directives inside the #ifndef ... #endif guard too. If your header was already seen, those headers were already included and don't need to be re-scanned again.
This is my header file
#ifndef LinkedList_H
#define LinkedList_H
#include <iostream>
#include "Node.h"
class LinkedList {
public:
int length;
// pointer to the first element of LinkedList
Node *head = 0;
// pointer to the last element of LinkedList
Node *tail = 0;
LinkedList();
~LinkedList();
};
#endif
and this is my.cpp file
#include "LinkedList.h"
using namespace std;
LinkedList::LinkedList() {
head=tail;
this->length=0;
}
LinkedList::~LinkedList() {
Node *current = head;
while(current!=NULL){
Node *temp = current;
current=current->next;
delete temp;
}
}
void add(string _name, float _amount){
Node *node = new Node(_name, _amount);
while(head==NULL){ //here, there is an error.
head=node;
head->next=tail;
}
}
int main(){
LinkedList *list = new LinkedList();
add("Adam", 7);
cout<<list->head<<endl;
}
In my .cpp file when I want to try to make an add function, it gives me an error in the while loop condition in add function. It says "head was not declared in this scope". But I declared in .h file. I couldn't see what is wrong.
You should use the resolution scope operator, just like you did for the constructor and the destructor.
So, you in your source file do this:
void LinkedList::add(string _name, float _amount) {
And then, of course, declare that function inside your class, in the header file.
Very likely the problem is circular includes. You probably have Node.h including LinkedList.h and vice-versa. This leads to (essentially) a paradox: If both class definitions require the other, which of the two is defined first in any given compilation unit?
In practice, you include Node.h, which then tries to include LinkedList.h again (note that #include literally means "copy-paste this file here" to the compiler), but at this point LinkedList_H is already defined (because that's where you came from) and the include has no effect. So now you are in the middle of Node.h but with no prior definition of LinkedList and get "not declared" errors.
The solution is to remove the #include Node.h in LinkedList.h and replace it with a forward declaration, since the LinkedList definition in the header doesn't need to know anything more than "the class Node exists" (because it only uses pointers).
I am implementing bptree using c++. I am am stuck in the initial step of node creation. Keep getting "C2011 'Node':'class' type redefinition" error. I found some suggestions online to remove class key word from cpp file. But when I remove class keyword I get lots of other errors. here is my code for Node.cpp:
#include "Node.h"
#include <cstdio>
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Node {
bool leaf;
Node** kids;
map<int, string> value;
int keyCount;//number of current keys in the node
//constructor;
Node::Node(int order) {
this->value = {};
this->kids = new Node *[order + 1];
this->leaf = true;
this->keyCount = 0;
for (int i = 0; i < (order + 1); i++) {
this->kids[i] = NULL;
}
}
};
and Node.h file is as following:
#pragma once
#ifndef NODE_HEADER
#define NODE_HEADER
class Node {
public:
Node(int order) {};
};
#endif
How can I fix this?
Problem
In C++, headers are simply pasted into the body when you #include. So now the compiler sees:
class Node {
public:
Node(int order) {};
};
// stuff from system headers omitted for brevity
using namespace std;
class Node {
bool leaf;
//...
};
There are two problems here:
compiler sees class Node twice with different bodies.
Node::Node is defined twice (first time empty {}).
Solution
The header should include class declaration:
#include <map>
using namespace std;
class Node {
bool leaf;
Node** kids;
map<int, string> value;
int keyCount;//number of current keys in the node
//constructor;
Node(int order);
};
Note that the constructor has no body here. It's just a declaration. Because it uses map you need to include <map> and add using namespace before the declaration.
After that don't put class Node again in the .cpp or .cc file. Only put the method implementations at the top level:
Node::Node(int order) {
// ...
}
This question already has answers here:
Circular C++ Header Includes
(6 answers)
Closed 7 years ago.
Hi...
#ifndef Node_H
#define Node_H
#include <vector>
#include <stack>
#include <string>
#include <iostream>
#include "Edge.h"
#include "CongestionMap.h"
using namespace std;
class Node
{
public:
Node(){ visit = false;};
Node(int id);
~Node();
int getID();
void setLocation(int &row, int &col, GridCell *Gc);;
void displayList();
private:
int row;
int col;
int id;
bool visit;
int parrent;
int distance;
typedef vector< Edge > adjNodeList;
};
#endif
When i compile the project i get error as
project\node.h(43): error C2065: 'Edge' : undeclared identifier
project\project\node.h(43): error C2923: 'std::vector' : 'Edge' is not a valid template type argument for parameter '_Ty'...
please help me ...
Edge.h
#ifndef Edge_H
#define Edge_H
#pragma once
#include <vector>
#include <stack>
#include <string>
#include <iostream>
#include "Node.h"
using namespace std;
class Edge
{
public:
Edge() {};
Edge(Node *firstNode, Node *secNode, int inCost);
~Edge(void);
Node* getDstNode();
Node* getOrgNode();
int getCost();
private:
Node *orgNode;
Node *dstNode;
int cost;
};
#endif
As some commenters have noted, you have circular references. The code is parsed in the order it appears.
If we start in node.h, early on, it includes edge.h.
edge.h includes node.h, but that cleverly won't do anything because of the #ifdef protection, and the redundant #pragma once (they both achieve the same thing, so you might consider sticking to just one approach).
Ok, the first class definition we would encounter is that for Edge. Great, except that it refers to Node, and nobody knows what that is...because we're still in the code for edge.h that's been included into node.h.
Likely you have things happening the other way around and edge.h is being included first. The next thing that happens is that node.h is included, and it declares Node, which expects to know what Edge is, but nobody has seen that yet.
So you'll need to use forward declaration, that is in edge.h before you declare class Edge, add a line indicating what Node is:
class Node;
and conversely in node.h, provide a forward declaration for Edge. The second one is to cover the case where somebody includes node.h before they include edge.h.
As an example, if you had them both declared in the same file you would still need to do something like:
class Node; // forward declaration so that compiler knows that
// Node is a class when it gets to parsing Edge
class Edge {
...
private:
Node *orgNode;
};
class Node {
....
};
}