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
Related
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) {
// ...
}
The tree.h file:
#ifndef tree
#define tree
#include "common.h"
#include "set.h"
/*Tree Structure*/
typedef struct
{
Set *set;
unsigned int setLength;
int vertexLength;
int *vertex;
int idle;
int parent;
int level;
int numberOfChildren;
} TreeNode;
typedef struct
{
TreeNode* node;
int nodeLength;
int height;
} Tree;
Tree* fill_tree(char *filename, int worldSize, int rank);
int get_number_of_leaves(Tree *tree);
TreeNode get_tree_node(int index, Tree* tree);
TreeNode* get_tree_nodes(Tree* tree);
int get_tree_nodes_length(Tree* tree);
void compute_level(int u, Tree* tree);
void print_tree(Tree* tree);
int get_max_level(Tree* tree);
int* create_task_list(Tree* tree, int* taskListLength, int rank);
int* map(int* taskList, int taskListLength, int* mapLength, int rank);
void generate_combination_sets(Tree* tree, int nodePerProcess, int rank);
#endif
The set.h file:
#ifndef set
#define set
#include "common.h"
#include "tree.h"
/*Tree Structure*/
typedef struct
{
int combinationLength;
int* combination;
} Set;
Set* generate_subsets(int* vertex, int vertexLength, unsigned int pow_set_size, int rank);
Set* match(Set* parent, unsigned int parentLength, Set* child, unsigned int childLength, TreeNode childNode, TreeNode parentNode, unsigned int* solutionLength, Graph* g, int rank);
int* union_operation(int* parenteCombination, int parentCombinationLength, int* childCombination, int childCombinationLength, unsigned int* mergedLength, int rank);
int not_in_solution(Set* solution, int solutionLength , int* merged, unsigned int mergedLength);
void print_set(Set set);
#endif
The common.h file:
#ifndef common
#define common
// Libraries
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <pthread.h>
#include <limits.h>
#include "mpi.h"
#include "graph.h"
#define true 1
#define false 0
#endif
I have errors that the tree and the set header files are codependent, and the compiler is giving me an error that set is not found in tree.h and likewise for set. Should I include all the fiels in the common.h file?
Use forward declarations when you need to reference the struct in another header file, the header does not need to know the details of the struct, try this in tree.h:
#ifndef tree
#define tree
#include "common.h"
// #include "set.h" <-- don't include set.h
typedef struct Set Set;
/*Tree Structure*/
typedef struct
{
Set *set;
unsigned int setLength;
int vertexLength;
...
} TreeNode;
in set.h:
typedef struct Set Set;
struct Set
{
int combinationLength;
int* combination;
} Set;
You write:
#define tree
and later in the same file:
int get_number_of_leaves(Tree *tree);
So tree is both a macro name and a variable. Not surprising that you receive errors!
Thats why macro names should not contain small characters, never.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
So, i am trying to do a program to generalize adding,deleting, showing a double linked list. but i have encountered a problem at the addition part. When compiling it i encounter " undefined reference to insertNodeBeggining(List*, void*)". What is the problem?
main.cpp
#include <iostream>
#include <cstring>
#include "methods.h"
using namespace std;
int main()
{
List *head=createList();
void *p=NULL;
insertNodeBeggining(head,p);
return 0;
}
methods.cpp
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <cstring>
#include <math.h>
using namespace std;
typedef struct nodeType{
nodeType *next;
nodeType *prev;
void* data;
} NodeT;
typedef struct Lists{
NodeT *first;
NodeT *last;
} List;
List *createList()
{
return (List*)malloc(sizeof(List));
}
void insertNodeBeggining(List *head, void *value)
{
NodeT *nou=(NodeT*)malloc(sizeof(NodeT));
nou->data=value;
if(head->first==NULL)
{
head->first=nou;
head->last=nou;
nou->next=NULL;
nou->prev=NULL;
}
else
{
nou->next=head->first;
head->first->prev=nou;
nou->prev=NULL;
head->first=nou;
}
}
methods.h
#ifndef METHODS_H_INCLUDED
#define METHODS_H_INCLUDED
typedef struct NodeT;
typedef struct List;
List *createList();
void insertNodeBeggining(List *head, void *value);
#endif // METHODS_H_INCLUDED
It seems that the problem is that the compiler considers two names List, one in the header and other in methods.cpp, as two different names.
The typedef in the header is invalid though the compiler may not issue an error
typedef struct List;
You should exclude these definitions
typedef struct nodeType{
nodeType *next;
nodeType *prev;
void* data;
} NodeT;
typedef struct Lists{
NodeT *first;
NodeT *last;
}List;
from metods.cpp and include them in the header instead of your typedef(s).
methods.cpp has to contain this new header included.
Basically, an incomplete type can't be completed via a typedef.
Hence your typedef-ed List in the implementation file is not considered to be a definition of the earlied forward-declared incomplete List.
To fix that, replace the C style
typedef struct Lists{
NodeT *first;
NodeT *last;
} List;
with C++ style
struct List
{
NodeT* first;
NodeT* last;
};
Disclaimer: I haven't run this through a compiler.
#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...
I'm trying to implement a tree-like structure with two classes: Tree and Node. The problem is that from each class I want to call a function of the other class, so simple forward declarations are not enough.
Let's see an example:
Tree.h:
#ifndef TREE_20100118
#define TREE_20100118
#include <vector>
#include "Node.h"
class Tree
{
int counter_;
std::vector<Node> nodes_;
public:
Tree() : counter_(0) {}
void start() {
for (int i=0; i<3; ++i) {
Node node(this, i);
this->nodes_.push_back(node);
}
nodes_[0].hi(); // calling a function of Node
}
void incCnt() {
++counter_;
}
void decCnt() {
--counter_;
}
};
#endif /* TREE_20100118 */
Node.h:
#ifndef NODE_20100118
#define NODE_20100118
#include <iostream>
//#include "Tree.h"
class Tree; // compile error without this
class Node
{
Tree * tree_;
int id_;
public:
Node(Tree * tree, int id) : tree_(tree), id_(id)
{
// tree_->incCnt(); // trying to call a function of Tree
}
~Node() {
// tree_->decCnt(); // problem here and in the constructor
}
void hi() {
std::cout << "hi (" << id_ << ")" << endl;
}
};
#endif /* NODE_20100118 */
Calling Tree:
#include "Tree.h"
...
Tree t;
t.start();
This is just a simple example to illustrate the problem. So what I want is calling a function of Tree from a Node object.
Update #1: Thanks for the answers. I tried to solve the problem like in Java, i.e. using just one file per class. It seems I will have to start separating .cpp and .h files...
Update #2: Below, following the hints, I pasted the complete solution too. Thanks, problem solved.
In the headers, forward declare the member functions:
class Node
{
Tree * tree_;
int id_;
public:
Node(Tree * tree, int id);
~Node();
void hi();
};
In a separate .cpp file that includes all the required headers, define them:
#include "Tree.h"
#include "Node.h"
Node::Node(Tree * tree, int id) : tree_(tree), id_(id)
{
tree_->incCnt();
}
Node::~Node()
{
tree_->decCnt();
}
etc
This also has the effect of keeping your headers readable, so it is easy to see a class's interface at a glance.
Following the hints, here is the complete solution.
Tree.h:
#ifndef TREE_20100118
#define TREE_20100118
#include "Node.h"
#include <vector>
class Tree
{
int counter_;
std::vector<Node> nodes_;
public:
Tree();
void start();
void incCnt();
void decCnt();
};
#endif /* TREE_20100118 */
Tree.cpp:
#include "Tree.h"
#include "Node.h"
Tree::Tree() : counter_(0) {}
void Tree::start()
{
for (int i=0; i<3; ++i) {
Node node(this, i);
this->nodes_.push_back(node);
}
nodes_[0].hi(); // calling a function of Node
}
void Tree::incCnt() {
++counter_;
}
void Tree::decCnt() {
--counter_;
}
Node.h:
#ifndef NODE_20100118
#define NODE_20100118
class Tree;
class Node
{
Tree * tree_;
int id_;
public:
Node(Tree * tree, int id);
~Node();
void hi();
};
#endif /* NODE_20100118 */
Node.cpp:
#include "Node.h"
#include "Tree.h"
#include <iostream>
Node::Node(Tree * tree, int id) : tree_(tree), id_(id)
{
tree_->incCnt(); // calling a function of Tree
}
Node::~Node() {
tree_->decCnt();
}
void Node::hi() {
std::cout << "hi (" << id_ << ")" << std::endl;
}
The definition of Tree requires the definition of Node but not the other way around so your forward declaration is correct.
All that you have to do is removed the definition of any functions that require a full definition of Tree from the Node class body and implement them in a .cpp file where full definitions of both classes are in scope.
Can you but the constructor/destructor bodies in a .cxx file? You could include Tree.h there.