I'm calling the default constructor and i'm confused why this gives an error
struct linkedlist
{
node* head = nullptr;
linkedlist();
linkedlist(vector <int> arr)
{
insert_nodes(arr);
}
....
1>Source.obj : error LNK2019: unresolved external symbol "public: __thiscall linkedlist::linkedlist(void)" (??0linkedlist##QAE#XZ)
but if I add curly braces after the constructor it runs fine
struct linkedlist
{
node* head = nullptr;
linkedlist()
{
}
linkedlist(vector <int> arr)
{
insert_nodes(arr);
}
....
I am trying to create a custom List in c++.
I've defined it this way:
List.h:
#include "ListItem.h"
#pragma once
template<class T> class List
{
private:
ListItem<T>* first;
public:
T* GetAt(int);
ListItem<T>* GetLastListItem();
void Add(T*);
void Clear();
};
List.cpp:
#include "stdafx.h"
#include "List.h"
template<class T> T* List<T>::GetAt(int index)
{
if (!first)
return 0;
ListItem<T>* current = first;
for (int i = 1; i < index; i++)
{
current = current->GetNext();
}
return current->GetItem();
}
template<class T> L...
main:
List<TestItem> liste;
TestItem ti; //just a int inside.
liste.Add(&ti);
I am getting the following errors:
1>ConsoleApplication1.obj : error LNK2019: unresolved external symbol ""public: void __thiscall List::Add(class TestItem *)" (?Add#?$List#VTestItem####QAEXPAVTestItem###Z)" in function"_main".
I've been given some source code (as part of an assignment) that I'm supposed to modify, but I can't get the unmodified version of the code to compile and I'm tearing my hair out. (To be clear - this code is for a school assignment on hash tables, these compile errors are not part of the assignment)
I'm using visual studio 2010 to compile. I've been working on this all day and getting absolutely nowhere!
I'm getting a series of "LNK2005" errors:
1>------ Build started: Project: Assignment10, Configuration: Debug Win32 ------
1> hashmain.cpp
1>e:\google drive\cpsc 1160\labs\projects\assignment10\assignment10\hashtable.cpp(40): warning C4018: '<' : signed/unsigned mismatch
1>hashtable.obj : error LNK2005: "public: __thiscall HashTableSavitch::HashTable::HashTable(void)" (??0HashTable#HashTableSavitch##QAE#XZ) already defined in hashmain.obj
1>hashtable.obj : error LNK2005: "public: virtual __thiscall HashTableSavitch::HashTable::~HashTable(void)" (??1HashTable#HashTableSavitch##UAE#XZ) already defined in hashmain.obj
1>hashtable.obj : error LNK2005: "private: static int __cdecl HashTableSavitch::HashTable::computeHash(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?computeHash#HashTable#HashTableSavitch##CAHV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in hashmain.obj
1>hashtable.obj : error LNK2005: "public: bool __thiscall HashTableSavitch::HashTable::containsString(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)const " (?containsString#HashTable#HashTableSavitch##QBE_NV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in hashmain.obj
1>hashtable.obj : error LNK2005: "public: void __thiscall HashTableSavitch::HashTable::put(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?put#HashTable#HashTableSavitch##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) already defined in hashmain.obj
1>E:\Google Drive\CPSC 1160\Labs\Projects\Assignment10\Debug\Assignment10.exe : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Here is the code I was given:
hashmain.cpp
// Program to demonstrate use of the HashTable class
#include <string>
#include <iostream>
#include "listtools.cpp" // Your compiler may compile separately
#include "hashtable.h"
#include "hashtable.cpp" // Your compiler may compile separately
using std::string;
using std::cout;
using std::endl;
using HashTableSavitch::HashTable;
int main()
{
HashTable h;
cout << "Adding dog, cat, turtle, bird" << endl;
h.put("dog");
h.put("cat");
h.put("turtle");
h.put("bird");
cout << "Contains dog? "
<< h.containsString("dog") << endl;
cout << "Contains cat? "
<< h.containsString("cat") << endl;
cout << "Contains turtle? "
<< h.containsString("turtle") << endl;
cout << "Contains bird? "
<< h.containsString("bird") << endl;
cout << "Contains fish? "
<< h.containsString("fish") << endl;
cout << "Contains cow? "
<< h.containsString("cow") << endl;
return 0;
}
hashtable.h
// This is the header file hashtable.h. This is the interface
// for the class HashTable, which is a class for a hash table
// of strings.
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <string>
#include "listtools.h"
using LinkedListSavitch::Node;
using std::string;
namespace HashTableSavitch
{
const int SIZE = 10;
class HashTable
{
public:
HashTable(); // Initialize empty hash table
// Normally a copy constructor and overloaded assignment
// operator would be included. They have been omitted
// to save space.
virtual ~HashTable(); // Destructor destroys hash table
bool containsString(string target) const;
// Returns true if target is in the hash table,
// false otherwise
void put(string s);
// Adds a new string to the hash table
private:
Node<string> *hashArray[SIZE];
static int computeHash(string s); // Compute hash value for string
}; // HashTable
} // HashTableSavitch
#endif // HASHTABLE_H
hashtable.cpp
// This is the implementation file hashtble.cpp.
// This is the implementation of the class HashTable.
#include <string>
#include "listtools.h"
#include "hashtable.h"
using LinkedListSavitch::Node;
using LinkedListSavitch::search;
using LinkedListSavitch::headInsert;
using std::string;
namespace HashTableSavitch
{
HashTable::HashTable()
{
for (int i = 0; i < SIZE; i++)
{
hashArray[i] = NULL;
}
}
HashTable::~HashTable()
{
for (int i=0; i<SIZE; i++)
{
Node<string> *next = hashArray[i];
while (next != NULL)
{
Node<string> *discard = next;
next = next->getLink( );
delete discard;
}
}
}
int HashTable::computeHash(string s)
{
int hash = 0;
for (int i = 0; i < s.length( ); i++)
{
hash += s[i];
}
return hash % SIZE;
}
bool HashTable::containsString(string target) const
{
int hash = this->computeHash(target);
Node<string>* result = search(hashArray[hash], target);
if (result == NULL)
return false;
else
return true;
}
void HashTable::put(string s)
{
int hash = computeHash(s);
if (search(hashArray[hash], s)==NULL)
{
// Only add the target if it's not in the list
headInsert(hashArray[hash], s);
}
}
} // HashTableSavitch
listtools.h
//This is the header file listtools.h. This contains type definitions and
//function declarations for manipulating a linked list to store data of any type T.
//The linked list is given as a pointer of type Node<T>* which points to the
//head (first) node of the list. The implementation of the functions are given
//in the file listtools.cpp.
#ifndef LISTTOOLS_H
#define LISTTOOLS_H
namespace LinkedListSavitch
{
template<class T>
class Node
{
public:
Node(const T& theData, Node<T>* theLink) : data(theData), link(theLink){}
Node<T>* getLink( ) const { return link; }
const T& getData( ) const { return data; }
void setData(const T& theData) { data = theData; }
void setLink(Node<T>* pointer) { link = pointer; }
private:
T data;
Node<T> *link;
};
template<class T>
void headInsert(Node<T>*& head, const T& theData);
//Precondition: The pointer variable head points to
//the head of a linked list.
//Postcondition: A new node containing theData
//has been added at the head of the linked list.
template<class T>
void insert(Node<T>* afterMe, const T& theData);
//Precondition: afterMe points to a node in a linked list.
//Postcondition: A new node containing theData
//has been added after the node pointed to by afterMe.
template<class T>
void deleteNode(Node<T>* before);
//Precondition: The pointers before point to nodes that has
//at least one node after it in the linked list.
//Postcondition: The node after the node pointed to by before
//has been removed from the linked list and its storage
//returned to the freestore.
template<class T>
void deleteFirstNode(Node<T>*& head);
//Precondition: The pointers head points to the first
//node in a linked list; with at least one node.
//Postcondition: The node pointed to by head has been removed
//for the linked list and its storage returned to the freestore.
template<class T>
Node<T>* search(Node<T>* head, const T& target);
//Precondition: The pointer head points to the head of a linked list.
//The pointer variable in the last node is NULL. head (first) node
//head (first) node has been defined for type T.
//(== is used as the criterion for being equal).
//If the list is empty, then head is NULL.
//Returns a pointer that points to the first node that
//is equal to the target. If no node equals the target,
//the function returns NULL.
}//LinkedListSavitch
#endif //LISTTOOLS_H
listtools.cpp
//This is the implementation file listtools.cpp. This file contains
//function definitions for the functions declared in listtools.h.
#include <cstddef>
#include "listtools.h"
namespace LinkedListSavitch
{
template<class T>
void headInsert(Node<T>*& head, const T& theData)
{
head = new Node<T>(theData, head);
}
template<class T>
void insert(Node<T>* afterMe, const T& theData)
{
afterMe->setLink(new Node<T>(theData, afterMe->getLink( )));
}
template<class T>
void deleteNode(Node<T>* before)
{
Node<T> *discard;
discard = before->getLink( );
before->setLink(discard->getLink( ));
delete discard;
}
template<class T>
void deleteFirstNode(Node<T>*& head)
{
Node<T> *discard;
discard = head;
head = head->getLink( );
delete discard;
}
//Uses cstddef:
template<class T>
Node<T>* search(Node<T>* head, const T& target)
{
Node<T>* here = head;
if (here == NULL) //if empty list
{
return NULL;
}
else
{
while (here->getData( ) != target && here->getLink( ) != NULL)
here = here->getLink( );
if (here->getData( ) == target)
return here;
else
return NULL;
}
}
}//LinkedListSavitch
I think that this is way out of my depth, I've poured over similar problems/solutions here and anywhere else I could find on google, but I'm completely stumped.
Edit:
As per the request of Arcinde, I commented out #include "hashtable.cpp" in hashmain.cpp like so:
#include <string>
#include <iostream>
#include "listtools.cpp" // Your compiler may compile separately
#include "hashtable.h"
//#include "hashtable.cpp" // Your compiler may compile separately
using std::string;
using std::cout;
using std::endl;
using HashTableSavitch::HashTable;
which produces the following errors:
1>------ Build started: Project: Assignment10, Configuration: Debug Win32 ------
1> hashmain.cpp
1>hashtable.obj : error LNK2019: unresolved external symbol "class LinkedListSavitch::Node<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > * __cdecl LinkedListSavitch::search<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class LinkedListSavitch::Node<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??$search#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###LinkedListSavitch##YAPAV?$Node#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###0#PAV10#ABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function "public: bool __thiscall HashTableSavitch::HashTable::containsString(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)const " (?containsString#HashTable#HashTableSavitch##QBE_NV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>hashtable.obj : error LNK2019: unresolved external symbol "void __cdecl LinkedListSavitch::headInsert<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(class LinkedListSavitch::Node<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > * &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (??$headInsert#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###LinkedListSavitch##YAXAAPAV?$Node#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###0#ABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function "public: void __thiscall HashTableSavitch::HashTable::put(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?put#HashTable#HashTableSavitch##QAEXV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
1>E:\Google Drive\CPSC 1160\Labs\Projects\Assignment10\Debug\Assignment10.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
It looks like the root of your problems was that you were instantiating template functions without an implementation (your .h was attempting to declare, and your .cpp was attempting to define them).
You have two options to resolve your issue:
Move everything from listtools.cpp into listtools.h, thus moving both the template instantiation and implementation to the same place
Move everything from listtools.cpp into a new file (listtoolssupport.h) and remove the declarations from listtools.h.
Using option 1, I moved all the implementations of listtools.cpp into listtools.h using #n0rd's and # Arcinde's instructions. I then completely removed the listtools.cpp as it now did nothing and removed the #includes of the .cpp.
listtools.h now looks like:
//This is the header file listtools.h. This contains type definitions and
//function declarations for manipulating a linked list to store data of any type T.
//The linked list is given as a pointer of type Node<T>* which points to the
//head (first) node of the list. The implementation of the functions are given
//in the file listtools.cpp.
#ifndef LISTTOOLS_H
#define LISTTOOLS_H
#include <cstddef>
namespace LinkedListSavitch
{
template<class T>
class Node
{
public:
Node(const T& theData, Node<T>* theLink) : data(theData), link(theLink) { }
Node<T>* getLink() const { return link; }
const T& getData() const { return data; }
void setData(const T& theData) { data = theData; }
void setLink(Node<T>* pointer) { link = pointer; }
private:
T data;
Node<T> *link;
};
template<class T>
void headInsert(Node<T>*& head, const T& theData)
{
head = new Node<T>(theData, head);
}
//Precondition: The pointer variable head points to
//the head of a linked list.
//Postcondition: A new node containing theData
//has been added at the head of the linked list.
etc etc etc...
The "Unresolved External Symbol" is basically saying that, when it goes to link, it cannot find a symbol for Node.
In your hashmain.cpp file
// Program to demonstrate use of the HashTable class
#include <string>
#include <iostream>
//#include "listtools.cpp" // Your compiler may compile separately
#include "hashtable.h"
//#include "hashtable.cpp" // Your compiler may compile separately
using std::string;
using std::cout;
using std::endl;
using HashTableSavitch::HashTable;
Try uncommenting the two commented lines.
It is wrong that include source code file name, so you should commented them.
This question might be similar to some others out there; however, my question here is pertaining to a Visual C++ issue. The following code for deleting a Binary Tree works fine with GNU's C++ compiler.
Tree_Node Class Definition:
class Tree_Node
{
friend class Binary_Tree;
public:
typedef int node_type;
node_type& data()
{
return value;
}
void data(node_type key)
{
this->value = key;
}
Tree_Node(node_type key) : value(key) {}
~Tree_Node();
private:
node_type value = 0;
Tree_Node* right = nullptr;
Tree_Node* left = nullptr;
};
Binary Tree Destructor Definition:
Binary_Tree::~Binary_Tree()
{
deleteTree(root);
}
void Binary_Tree::deleteTree(Tree_Node* node)
{
if (node)
{
deleteTree(node->left);
deleteTree(node->right);
cout << node->data();
delete node;
}
}
However, while giving Visual C++ a try, the same code is giving out a couple of strange errors:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall
Tree_Node::~Tree_Node(void)" (??1Tree_Node##QAE#XZ) referenced in
function "public: void * __thiscall Tree_Node::`scalar deleting
destructor'(unsigned int)" (??_GTree_Node##QAEPAXI#Z)
E:\Workspace\BinaryTree\BinaryTree\BinaryTree_Methods.obj
Error 2 error LNK1120: 1 unresolved externals
E:\Workspace\BinaryTree\Debug\BinaryTree.exe
The problem seems to be arising specifically from the delete node; statement. What am I missing here?
Did you make a destructor for node?
Like Declare and define ~Tree_Node()
This question already has answers here:
Why do I get "unresolved external symbol" errors when using templates? [duplicate]
(3 answers)
Why can templates only be implemented in the header file?
(17 answers)
Why do C++ template definitions need to be in the header? [duplicate]
(5 answers)
Closed 9 years ago.
I have created a list and it worked perfectly, but I have to rewrite it using template, I have done this. But when I trying to compile my code I get Linker Error!
Can you help with this code? Any help would be much appreciated!
This is List.h
#pragma once
#include <cstdlib>
template <class T>
class List
{
public:
struct Node
{
T data;
Node *next, *prev;
Node();
Node(T &smth);
~Node();
};
Node *head;
Node *tail;
public:
List();
~List();
void add(T &d);
void del(Node *);
};
List.cpp
#include "List.h"
template <class T>
List<T>::List()
{
}
template <class T>
List<T>::~List()
{
Node*n;
while (head != nullptr)
{
n = head->prev;
delete head;
head = n;
}
}
template <class T>
void List<T>::add(T &d)
{
Node *n = new Node(d);
n->prev = head;
n->next = nullptr;
if (head!=nullptr)
head->next = n;
if(head == nullptr){
head = n;
tail = head;
} else
head = n;
}
template <class T>
void List<T>::del(Node *node)
{
if (head == node)
head = node->prev;
if (tail == node)
tail = node->next;
if (node->next != nullptr)
node->next->prev = node->prev;
if (node->prev != nullptr)
node->prev->next = node->next;
delete node;
}
template <class T>
List<T>::Node::Node():data(),next(nullptr),prev(nullptr){}
template <class T>
List<T>::Node::Node(T &smth):data(smth),next(nullptr),prev(nullptr){}
template <class T>
List<T>::Node::~Node(){
data.~Word();
next = nullptr;
prev = nullptr;
}
and main.cpp
#include <List.h>
#include <iostream>
using namespace std;
int main()
{
int a;
List<int> my;
cin >> a;
my.add(a);
cin >> a;
my.add(a);
cin >> a;
my.add(a);
}
and I get these errors:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall >List::List(void)" (??0?$List#H##QAE#XZ) referenced in function _main >c:\Users\lapchenko\documents\visual studio >2012\Projects\ConsoleApplication1\ConsoleApplication1\Source.obj
Error 2 error LNK2019: unresolved external symbol "public: __thiscall >List::~List(void)" (??1?$List#H##QAE#XZ) referenced in function _main >c:\Users\lapchenko\documents\visual studio >2012\Projects\ConsoleApplication1\ConsoleApplication1\Source.obj
Error 3 error LNK2019: unresolved external symbol "public: void __thiscall >List::add(int &)" (?add#?$List#H##QAEXAAH#Z) referenced in function _main >c:\Users\lapchenko\documents\visual studio >2012\Projects\ConsoleApplication1\ConsoleApplication1\Source.obj
Error 4 error LNK1120: 3 unresolved externals c:\users\lapchenko\documents\visual >studio 2012\Projects\ConsoleApplication1\Debug\ConsoleApplication1.exe 1