This question already has answers here:
Undefined reference to destructor error in c++?
(2 answers)
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 11 months ago.
I have a AVL class like this, it's templated and it gives error in main, I have tried to debug it for hours but it didn't fixed. What can be the problem? What part am I missing? It can be related to constructors but I tried that and it didn't fixed. I'm using Visual Studio 2012 and I feel stuck.
The error is:
1>Ege_HW2.obj : error LNK2019: unresolved external symbol "public: __thiscall AvlTree<struct item>::~AvlTree<struct item>(void)" (??1?$AvlTree#Uitem####QAE#XZ) referenced in function __unwindfunclet$??0AVLSection##QAE#XZ$0
1>Ege_HW2.obj : error LNK2019: unresolved external symbol "public: __thiscall AvlTree<struct AVLSection>::~AvlTree<struct AVLSection>(void)" (??1?$AvlTree#UAVLSection####QAE#XZ) referenced in function _main
1>fatal error LNK1120: 2 unresolved externals
Header file:
#ifndef AVLTREE_H
#define AVLTREE_H
#include <iostream>
#include <string>
using namespace std;
/* AVL Tree is taken from the lecture slides. */
template <class Comparable>
class AvlTree;
template <class Comparable>
class AvlNode
{
Comparable element;
AvlNode* left;
AvlNode* right;
int height;
AvlNode(const Comparable& theElement,
AvlNode* lt, AvlNode* rt, int h = 0)
: element(theElement), left(lt), right(rt), height(h) { }
friend class AvlTree<Comparable>;
};
template <class Comparable>
class AvlTree
{
public:
explicit AvlTree();
explicit AvlTree(const Comparable& notFound);
AvlTree(const AvlTree& rhs);
~AvlTree();
const Comparable& findMin() const;
const Comparable& findMax() const;
const Comparable& find(const Comparable& x) const;
bool isEmpty() const;
void printTree() const;
void makeEmpty();
void insert(const Comparable& x);
void remove(const Comparable& x);
const AvlTree& operator=(const AvlTree& rhs);
private:
AvlNode<Comparable>* root;
const Comparable ITEM_NOT_FOUND;
const Comparable& elementAt(AvlNode<Comparable>* t) const;
void insert(const Comparable& x, AvlNode<Comparable>*& t) const;
void remove(const Comparable& x, AvlNode<Comparable>*& t) const;
AvlNode<Comparable>* findMin(AvlNode<Comparable>* t) const;
AvlNode<Comparable>* findMax(AvlNode<Comparable>* t) const;
AvlNode<Comparable>* find(const Comparable& x, AvlNode<Comparable>* t) const;
void makeEmpty(AvlNode<Comparable>*& t) const;
void printTree(AvlNode<Comparable>* t) const;
AvlNode<Comparable>* clone(AvlNode<Comparable>* t) const;
// Avl manipulations
int height(AvlNode<Comparable>* t) const;
int max(int lhs, int rhs) const;
void rotateWithLeftChild(AvlNode<Comparable>*& k2) const;
void rotateWithRightChild(AvlNode<Comparable>*& k1) const;
void doubleWithLeftChild(AvlNode<Comparable>*& k3) const;
void doubleWithRightChild(AvlNode<Comparable>*& k1) const;
};
#include "AvlTree.cpp"
#endif
Cpp file:
#include "avlTree.h"
#include <iostream>
using namespace std;
template <class Comparable>
AvlTree<Comparable>::AvlTree(){
root = NULL;
}
/*** Construct the tree.
*/
template <class Comparable>
AvlTree<Comparable>::AvlTree(const Comparable& notFound)
:ITEM_NOT_FOUND(notFound), root(NULL){}
/*** Copy constructor.*/
template <class Comparable>
AvlTree<Comparable>::AvlTree(const AvlTree<Comparable>& rhs)
: root(NULL), ITEM_NOT_FOUND(rhs.ITEM_NOT_FOUND) {
*this = rhs;
}
And finally the main:
#include <iostream>
#include <string>
#include "BinaryTree.h"
#include "AvlTree.h"
#include <fstream>
using namespace std;
struct item{
string title;
string information;
item(){};
};
struct AVLSection{
AvlTree<item> avlSection;
string sectionTitle;
AVLSection(){};
};
struct BSTSection{
BinarySearchTree <item> bstSection;
string sectionTitle;
BSTSection(){}
};
void readData(BinarySearchTree<BSTSection> & bst, AvlTree<AVLSection> & avl){
ifstream input;
string filename = "data.txt",line;
input.open(filename.c_str());
while(getline(input,line)){
cout << line;
}
}
int main(){
BinarySearchTree<BSTSection> bst;
AvlTree<AVLSection> avl;
}
Related
I had a redefinition problem but I noticed that I already included .cpp file in the .hpp file so my mistake was including the .hpp file in my .cpp file again
Now I am getting this error, something to do with templates.
Also while you fix my problem, can you explain to me what template class does?
cplusplus.com is not that descriptive.
Thank you. :)
//implementation
template<class T>
ArrayBag<T>::ArrayBag() : item_count_(0){}
-------------WARNING YOU ARE NOW LEAVING IMPLEMENTATION---------------------------
//interface
#ifndef ARRAY_BAG_H
#define ARRAY_BAG_H
#include <vector>
template<class T>
class ArrayBag
{
protected:
static const int DEFAULT_CAPACITY = 200;
T items_[DEFAULT_CAPACITY];
int item_count_;
int get_index_of_(const T& target) const;
public:
ArrayBag();
int getCurrentSize() const;
bool isEmpty() const;
//adds a new element to the end, returns true if it was successfully been added
bool add(const T& new_entry);
bool remove(const T& an_entry);
void clear();
bool contains(const T& an_entry) const;
int getFrequencyOf(const T& an_entry) const;
std::vector<T> toVector() const;
void display() const;
//overloading operators for objects
void operator+=(const ArrayBag<T>& a_bag);
void operator-=(const ArrayBag<T>& a_bag);
void operator/=(const ArrayBag<T>& a_bag);
};
#include "ArrayBag.cpp"
#endif
-------------WARNING YOU ARE NOW LEAVING INTERFACE---------------------------
//error
5 C:\Users\minahnoona\Desktop\ArrayBag.cpp expected constructor, destructor, or type conversion before '<' token
5 C:\Users\minahnoona\Desktop\ArrayBag.cpp expected `;' before '<' token
Don't call your ArrayBag.cpp a .cpp file. Template implementations go in header files, and the name should reflect that.
If you want the implementation in a separate file (you don't strictly need to), call it ipp or tpp. Something the project system won't try to compile on its own.
Then include it from the .hpp and don't include the .hpp from the .ipp.
I am writing two templated classes (for academic reasons):
'class Vector', which mimics a C++ vector using a dynamic array.
'class Set', which creates a set using a vector object.
Vector.cpp -
#ifndef __CS_VECTOR_H_
#define __CS_VECTOR_H_
#include <cstdlib>
#include "Set.cpp"
template <class Type>
class Vector
{
public:
Vector(unsigned int capacity = DEFAULT_CAPACITY);
Vector(const Vector<Type>& rhs);
~Vector();
unsigned int capacity() const;
unsigned int size() const;
bool empty() const;
void push_back(const Type& data);
bool remove(const Type& data);
void clear();
bool at(unsigned int pos, Type& data) const;
int get_array_size() const;
Type& operator[](unsigned int pos) const;
Vector& operator=(const Vector& rhs);
private:
static const unsigned int DEFAULT_CAPACITY = 3;
void generate_larger_array(unsigned int capacity);
int array_size_ = 0;
int array_capacity_;
Type *array_;
};
//Function definitions here.
//#include "Set.cpp"
#endif
Set.cpp -
#ifndef __CS_SET_H_
#define __CS_SET_H_
#include "Vector.cpp"
template <class Comparable>
class Set
{
public:
unsigned int size() const;
bool empty() const;
bool contains(const Comparable& data) const;
bool insert(const Comparable& data);
bool remove(const Comparable& data);
void clear();
int get_size();
private:
int element_;
Vector<Comparable> set_;
};
//Function definitions here
//#include "Vector.cpp"
#endif
Main.cpp
#include "Set.cpp"
#include "Vector.cpp"
When I compile my code, I receive an error telling me:
error: ‘Vector’ does not name a type Vector<Comparable> set_;
When declaring my set_ object in Set.
These are both cpp files that are included into a file main.cpp. The set cpp file does contain the #include vector.cpp and vice versa
main.cpp just has code that tests the class functionality. I receive this error when attempting to compile either the main.cpp file. The main.cpp file is written by my instructor, so I am not entirely sure I should post it here.
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 7 years ago.
The solution to the duplicate question did not work
I have the following files:
ListaEnc.hpp
#include "Elemento.hpp"
template<typename T>
class ListaEnc {
public:
ListaEnc();
~ListaEnc();
// inicio
void adicionaNoInicio(const T& dado);
T retiraDoInicio();
void eliminaDoInicio();
T pegarHead();
// posicao
void adicionaNaPosicao(const T& dado, int pos);
int posicao(const T& dado) const;
T* posicaoMem(const T& dado) const;
bool contem(const T& dado);
T retiraDaPosicao(int pos);
// fim
void adiciona(const T& dado);
T retira();
// especifico
T retiraEspecifico(const T& dado);
void adicionaEmOrdem(const T& data);
// outras
bool listaVazia() const;
bool igual(T dado1, T dado2);
bool maior(T dado1, T dado2);
bool menor(T dado1, T dado2);
void destroiLista();
int pegarTamanhoLista();
private: //trocar pra private
Elemento<T>* head;
int size;
};
ListaEnc.cpp
#include "ListaEnc.hpp"
#include <cstdlib>
#include <iostream>
template<typename T>
ListaEnc<T>::ListaEnc()
{
...
}
main.cpp
#include "ListaEnc.hpp"
using namespace std;
int main(int argc, char** argv)
{
double x1, y1;
x1 = 2; y1 = 4.2;
ListaEnc<int>* teste = new ListaEnc<int>();
return 0;
}
This should compile just fine, but I get an undefined reference error to ListaEnc on main.cpp. I have more files in which the reference to ListaEnc is also undefined, but I tried isolating it and still can't get it to work. Does anyone understand why this is happening?
edit: More specifically, there is an undefined error to the constructor and destructor of ListaEnc
You can't separate declaration from implementation when you instantiate a template class. Combine your code to a single file and include that in your main.cpp.
Or, even go a step further and implement the functions inline in your class declaration if that suits your coding style.
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 8 years ago.
I read many of the other questions about this linker error, but I still wasn't able to solve it yet...
vector.hpp
#ifndef vector_hpp
#define vector_hpp
namespace vec
{
template<class T> class Vector
{
private:
T* arr;
unsigned int numberOfElements;
public:
Vector();
~Vector();
void push_back(const T&);
void pop_back();
void pop_front();
unsigned int size() const;
T& at(int);
T& front();
bool empty() const;
T& operator[](const int) const;
};
}
#endif
vector.cpp (not everything, would be too long)
#include "vector.hpp"
#include <iostream>
namespace vec
{
template<class T>
Vector<T>::Vector()
: arr(nullptr), numberOfElements(0)
{
return;
}
template<class T>
Vector<T>::~Vector()
{
delete[] arr;
}
template<class T>
unsigned int Vector<T>::size() const
{
return numberOfElements;
}
...
}
patientenliste.hpp
#ifndef patientenliste_hpp
#define patientenliste_hpp
#include "vector.hpp"
#include <iostream>
#include "patient.hpp"
using namespace std;
class Patientenliste
{
private:
vec::Vector<Patient> liste;
public:
Patientenliste& operator+= (const Patient&);
vec::Vector<Patient>& getPListe();
friend ostream& operator<< (ostream&, const Patientenliste&);
};
ostream& operator<< (ostream&, const Patientenliste&);
#endif
patientenliste.cpp
#include "patientenliste.hpp"
Patientenliste& Patientenliste::operator+= (const Patient& p)
{
liste.push_back(p);
return *this;
}
vec::Vector<Patient>& Patientenliste::getPListe()
{
return liste;
}
ostream& operator<< (ostream& os, const Patientenliste& p)
{
if(p.liste.size() == 0)
os << "Keine Patienten in der Liste.";
else
for(unsigned int i=0; i < p.liste.size(); i++)
os << p.liste[i] << endl;
return os;
}
I have some more files/classes in my project but every class which uses my Vector-class I get the Linker-error:
patientenliste.cpp:(.text+0x32): Nicht definierter Verweis auf vec::Vector<Patient>::size() const'
patientenliste.cpp:(.text+0x5e): Nicht definierter Verweis aufvec::Vector::size() const'
patientenliste.cpp:(.text+0x6c): Nicht definierter Verweis auf `vec::Vector::operator [ ] (int) const'
(in english "Nicht definierter Verweis auf" means "undefined reference to")
I have absolutely no clue about what's going wrong...
I already tried it wihtout the namespace vec, but that didn't work either.
Template definitions shall be in the same header file where the corresponding template class is defined.
This question already has answers here:
Why can templates only be implemented in the header file?
(17 answers)
Closed 8 years ago.
This is my code and I am getting a linking problem on the constructor:
#ifndef LOCKFREEQUEUE_H
#define LOCKFREEQUEUE_H
#include <atomic>
#include <memory>
template<typename T>
class lock_free_queue
{
private:
struct node
{
std::shared_ptr<T> data;
node* next;
node():next(nullptr){}
};
std::atomic<node*> head;
std::atomic<node*> tail;
node* pop_head()
{
node* const old_head=head.load();
if(old_head==tail.load())
{
return nullptr;
}
head.store(old_head->next);
return old_head;
}
lock_free_queue(const lock_free_queue& other);
lock_free_queue& operator=(const lock_free_queue& other);
public:
lock_free_queue();
~lock_free_queue();
std::shared_ptr<T> pop();
void push(T new_value);
};
Source file:
#include "lock_free_queue.h"
template<typename T>
lock_free_queue<T>::lock_free_queue(const lock_free_queue& other)
{
}
template<typename T>
lock_free_queue<T>& lock_free_queue<T>::operator=(const lock_free_queue& other)
{
}
template<typename T>
lock_free_queue<T>::lock_free_queue():head(new node),tail(head.load())
{
}
template<typename T>
lock_free_queue<T>::~lock_free_queue()
{
while(node* const old_head=head.load())
{
head.store(old_head->next);
delete old_head;
}
}
template<typename T>
std::shared_ptr<T> lock_free_queue<T>::pop()
{
node* old_head=pop_head();
if(!old_head)
{
return std::shared_ptr<T>();
}
std::shared_ptr<T> const res(old_head->data);
delete old_head;
return res;
}
template<typename T>
void lock_free_queue<T>::push(T new_value)
{
std::shared_ptr<T> new_data(std::make_shared<T>(new_value));
node* p=new node;
node* const old_tail=tail.load();
old_tail->data.swap(new_data);
old_tail->next=p;
tail.store(p);
}
Main:
#include "lock_free_queue.h"
int main(){
lock_free_queue<int>* my_queue = new lock_free_queue<int>();
my_queue->push(3);
return 1;
}
Linker error:
Main.obj : error LNK2019: unresolved external symbol "public: __cdecl lock_free_queue<int>::lock_free_queue<int>(void)" (??0?$lock_free_queue#H##QEAA#XZ) referenced in function main
Main.obj : error LNK2019: unresolved external symbol "public: void __cdecl lock_free_queue<int>::push(int)" (?push#?$lock_free_queue#H##QEAAXH#Z) referenced in function main
I can't see why these aren't linking?
The template class definition and its member function realizations shall be in one header file.