I'm making a heap class to be importable with heap.h
and my constructors including bool types do not work, yet every other constructor and function imported works.
Here is what's in heap.h
:
#ifndef __HEAP_INCLUDED__
#define __HEAP_INCLUDED__
#include <iostream>
#include <vector>
using namespace std;
class heap{
int capacity;
bool isMinHeap; //1 is min heap -- ascending order
vector<int> * content;
public:
heap();
heap(bool t);
heap(vector<int> * input);
heap(vector<int> * input, bool t);
void print();
void prettyPrint();
int parent(int i);
int leftChild(int i);
int rightChild(int i);
int size();
int getMax();
void insert(int data);
void heapifyDown(int index);
void heapifyUp(int index);
int invalidChild(int index);
int deleteMax();
int deleteMin();
bool minDir();
int at(int index);
};
vector<int> * heapSort(vector<int> * input);
void swap(vector<int> * vec, int a, int b);
#endif
Here are the defined constructors in heap.cpp
. Note, all constructors work fine when I add a main to this file to test stuff:
class heap{
vector<int> * content;
int capacity = 256;
bool isMinHeap; //1 is min heap -- ascending order
public:
heap(){
content = new vector<int>;
isMinHeap = 0;
}
heap(bool t){
content = new vector<int>;
isMinHeap = t;
}
heap(vector<int> * input){
content = input;
isMinHeap = true;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
heap(vector<int> * input, bool t){
content = input;
isMinHeap = t;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
//other functions below
}
The constructors with bool do not work in main.cpp
, which has #include "heap.h"
at the top. The files are all in the same directory and I am compiling with this command: g heap.cpp main.cpp -o main
. Why do two of my constructors not work?
The error I see is
/usr/bin/ld: /tmp/ccwomODk.o: in function `main':
main.cpp:(.text 0x4e2): undefined reference to `heap::heap(bool)'
collect2: error: ld returned 1 exit status
-Wall
does not elaborate on the issue. I'm pretty sure the issue is with my linking somewhere because the constructors work inside of heap.cpp
when I use them in there.
CodePudding user response:
What you are doing with the class in the .cpp
file is wrong. You are not allowed to define the class twice. There must only be one class heap { /*...*/ };
in the program (but it may be included in multiple .cpp
files). Otherwise the one-definition-rule (ODR) is violated and the program has undefined behavior.
So remove everything you are showing from heap.cpp
.
To define the constructors of heap
in the heap.cpp
file, you need to use this syntax:
#include "heap.h"
heap::heap() {
/*...*/
}
heap::heap(bool t) {
/*...*/
}
//...
and so on. The other member functions must be defined in a similar way, e.g.:
void heap::print() {
/*...*/
}
Furthermore, if you want to have a default member initializer as in
int capacity = 256;
add it in the declaration in the .h
file instead.
I also want to add that having a pointer-to-std::vector
as member is almost surely a wrong approach as well, but out-of-scope for the question.
CodePudding user response:
When you declare a program element such as a class, function, or variable, its name can only be "seen" and used in certain parts of your program. The context in which a name is visible is called its scope. For example, if you declare a variable x within a function, x is only visible within that function body.
It seems you broke ODR rule so bad. Your class members including constructors has no body declared in the source file(heap.cpp). Use '::' to make class members have a body:
//heap.cpp
"heap.h"
heap::heap()
{
}
heap:heap(vector<int> * input, bool t)
{
}
int heap::parent(int i)
{
return i;
}
// this is how you create a body for function that are class members
// the same should be done for all other functions