For a school project I am trying to make a binary search tree at the same time we are supposed to learn how to use 'friendship' in classes. The errors I get while compiling are: [I put comments in code where the errors originate from for clarity]
$ make -f makefile.txt
g++ -Wall -W -Werror -pedantic -g -c BST.cpp
BST.cpp: In member function `void BST::insert(std::string, std::string)':
BST.cpp:13: error: invalid use of undefined type `struct Node'
BST.h:19: error: forward declaration of `struct Node'
makefile.txt:9: recipe for target `BST.o' failed
make: *** [BST.o] Error 1
Basically I want to be able to access the Node class as if the class was nested (I am not allowed to nest it for the sake of this programming assignment however). Obviously simply using 'ptr->m_data' would not work, but what could I do to make it work?
Node.h
#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
class BST;
class Node
{
public:
Node(string key, string data)
{n_key = key; n_data = data;}
~Node();
private:
string m_key;
string m_data;
Node *m_left;
Node *m_right;
//Node *m_parent;
};
#endif // NODE_H_INCLUDED
BST.h
#ifndef BST_H_INCLUDED
#define BST_H_INCLUDED
#include <iostream>
#include <string>
using namespace std;
class BST
{
public:
BST()
{m_root = NULL;}
~BST();
void insert(string key, string data);
void find(string key);
void remove(string key, string data);
void print();
friend class Node; //Error: forward declaration of 'struct Node'
private:
Node* m_root;
};
#endif // BST_H_INCLUDED
Why is it that when I call the below line of code it reads out the above error messages? (Note: the below code is from BST.cpp)
#include "BST.h"
void BST::insert(string key, string data)
{
Node* yPtr = NULL;
Node* xPtr = m_root;
while(xPtr != NULL)
{
yPtr = xPtr;
if(key < xPtr->m_key) //Error: invalid use of undefined type 'struct Node'
{
}
}
}
The compiler has not seen the definition of Node when it gets to that line in BST.cpp. Note that that is the first line where the compiler needs to see the structure of Node. You need to #include "Node.h" in BST.cpp.
Related
I'm trying to define Node into NodeList class, And store it.
Whay I've tried is:
In Try() function, I defined a node like Node *node = malloc... This works fine. But if I use the node that I defined in class like node = malloc... this line gives runtime error. I don't understand what is the difference between these two.
Here are classes:
Node.hpp
#ifndef NODE_HPP
#define NODE_HPP
class Node{
public:
int data;
};
#endif
Node.cpp
#include <iostream>
#include "Node.hpp"
using namespace std;
NodeList.hpp
#ifndef NODELIST_HPP
#define NODELIST_HPP
#include "Node.hpp"
class NodeList{
public:
Node *node;
void Try();
};
#endif
NodeList.cpp
#include <iostream>
#include "NodeList.hpp"
#include "Node.hpp"
using namespace std;
void NodeList::Try(){
//This works (doesn't give error):
//Node *node = (Node*)malloc(sizeof(Node));
//But I use the node I defined in class here and this line gives runtime error:
node = (Node*)malloc(sizeof(Node));
}
Main.cpp
#include <iostream>
#include "NodeList.hpp"
using namespace std;
int main()
{
NodeList *node = NULL;
node->Try();
system("PAUSE");
return 0;
}
You code has many problems:
In Main.cpp you are dereferencing a NULL pointer: node->DosyaOku();, but node is NULL. This is an undefined behavior.
You have the same problem in NodeList.cpp
You are using a malloc in Node.cpp and you should probably want to use a new instead (read here), and you should think how to free/delete that pointer.
The Create in Node.cpp has a parameter that is overwritten immediately, that looks like an error.
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.
I'm having trouble unsing my AVL tree class in one of my programs, I'm not sure how to include my class and use it with existing code, here is the problem:
I have an AVL tree class: AVL_tree.h and AVL_tree.cpp
I also have a main.cpp file
Also functions.cpp and functions.h, where I store some functions used in main.cpp
So, in main() I create an object from my AVL tree class. I want to pass this object along with some other data (which will serve to change the information stored in the tree) to one of the functions from my functions.cpp. And here is where I can't get it to work. I get several errors like these ones:
main.o:main.cpp|| undefined reference to `AVL_Tree::AVL_Tree()'|
main.o:main.cpp|| undefined reference to `process_vector(std::vector<int, std::allocator<int> >, AVL_Tree&)'|
How can I pass the necessary information to my function in order to modify my tree?
Simplified version of my code files:
main.cpp
#include <vector>
#include "functions.h"
#include "AVL_tree.h"
using namespace std;
int main() {
AVL_Tree tree;
vector<int> V;
V.push_back(11);
V.push_back(4);
V.push_back(7);
process_vector(V, tree);
return 0;
}
functions.h
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
#include<vector>
#include"AVL_tree.h"
using namespace std;
void process_vector(vector<int> V, AVL_Tree &tree);
#endif // FUNCTIONS_H
functions.cpp
#include<vector>
#include"functions.h"
#include"AVL_tree.h"
using namespace std;
void process_vector(vector<int> V, AVL_Tree &tree){
for(int i=0;i<vector.size();i++){
key = vector[i]
tree.AddLeaf(key);
}
return;
}
AVL_tree.h
#ifndef AVL_TREE_H
#define AVL_TREE_H
class AVL_Tree{
private:
struct node{
int key;
node* left;
node* right;
};
node* root;
node* CreateLeaf(int key);
node* AddLeafPrivate(int key, node* Ptr);
int HeightPrivate(node* Ptr);
int BFactorPrivate(node* Ptr);
public:
AVL_Tree();
void AddLeaf(int key);
int Height(int key);
int BFactor(int key);
};
#endif // TREE
Context: I've got a class Node like this:
#ifndef NODE_H_
#define NODE_H_
template <class T>
class Node
{
private:
T data;
Node* next;
Node* previous;
public:
Node();
Node(T);
~Node();
};
#endif /* NODE_H_ */
And a class ListDE like this:
/*
* ListDE.h
*
* Created on: Apr 22, 2013
* Author: x
*/
#ifndef LIST_H_
#define LIST_H_
#include <iostream>
#include <fstream>
#include <string>
#include "Node.h"
using namespace std;
template <class T>
class ListDE
{
private:
int qElements;
Node<T>* start;
Node<T>* getNextNode(Node<T>* aNode);
public:
ListDE();
~ListDE();
Node<T> getFirstPosition();
int getQNodes();
void setQNnodes(int q);
Node<T>* getNode(int pos);
T get_data(int pos);
void change_value(int pos, T newValue);
void add_new_data(T data);
void concat(ListDE<T>* otherList);
void delete_last();
};
#endif /* LIST_H_ */
Problem: when I try to compile, I get these errors:
ListDE.h:24:5: error: ‘Node’ is not a template
ListDE.h:26:5: error: ‘Node’ is not a template
ListDE.h:26:34: error: ‘Node’ is not a template
ListDE.h:32:5: error: ‘Node’ is not a template
ListDE.h:35:5: error: ‘Node’ is not a template
Can anyone explain to me what these mean? Thanks!
Add the following line to Node.h
#error Found the right Node.h
Then, adjust your include paths until you hit that error.
Finally, comment it out again.
#ifndef SLIST_H
#define SLIST_H
#include "llist.h"
using namespace std;
class slist:public llist{
public:
slist();
int search(el_t Key);
void replace(el_t Elem, int I);
};
#endif
That is my new class I just made that gives me the search and replace function, on top of all the inherited functions contained in llist.h
In my main...
#include "slist.h"
#include <iostream>
using namespace std;
int main(){
slist list;
list.addFront(4);
cout<<list.search(4);
}
I'm trying to call addfront() which is a public function in the llist class. Then I want to call search() which is an inherited public function of the slist class. g++ gives me a few errors that I don't understand.
slist.h: In function âint main()â:
slist.h:10: error: âslist::slist()â is protected
main.cpp:7: error: within this context
slist() is protected? Why's that? I put it under public:
Also whats up with the this context, I'm guessing I'm just doing the whole inheritance thing totally wrong. Any help would be appreciated!
Edit: Here's the llist class, if it helps
#ifndef LIST_H
#define LIST_H
#include <iostream>
using namespace std;
class llist{
protected:
typedef int el_t;
el_t total;
struct Node{
int Elem;
Node *Next;
};
Node *Front;
Node *Rear;
Node * Curr;
public:
class Overflow{};
class Underflow{};
class Range{};
llist();
~llist();
bool isEmpty();
void displayAll();
void addRear(el_t NewNum);
void deleteFront(el_t& OldNum);
void addFront(el_t NewNum);
void deleteRear(el_t& OldNum);
void deleteIth(int I, el_t& OldNum);
void addbeforeIth(int I, el_t newNum);
class Overflow;
};
#endif
This is llist.cpp with only the relevant functions pasted
#include "llist.h"
#include <iostream>
using namespace std;
int total=0;
llist::llist(){
Front=NULL;
Rear=NULL;
total=0;
}
llist::~llist(){
while(Front!=NULL){
int z;
deleteFront(z);
}
}
bool llist::isEmpty(){
if(Front==NULL){
return true;
}
return false;
}
void llist::displayAll(){
Curr=Front;
if(isEmpty()){
cout<<"[ empty ]"<<endl;
}else{
while(Curr!=NULL){\
cout<<"curr != NuL"<<endl;
cout<<Curr->Elem<<endl;
Curr=Curr->Next;
}
}
}
void llist::addFront(el_t NewNum){
if(isEmpty()){
Node *x=new Node;
x->Next=Front;
Rear=Front;
Front=x;
Front->Elem=NewNum;
}else{
Node *x=new Node;
x->Next=Front;
Front=x;
Front->Elem=NewNum;
++total;
}
}
I honestly can't see the problem but not every compiler is standard-compliant, so I would try the following:
1) Rename your class - if it works, that means it's a because of a naming conflict.
2) Remove the using directives.
3) Remove the inheritance. If it works after this... you really need to change compilers.
4) Try #undef public before your class declaration. If it works after this... well, someone's in for a talk with the manager.
5) Pray...