c++ - "unresolved external symbol public: __thiscall" on BST, most likely due to templates -
well, tried looking through net solution couldn't find fixed problem.
i writing assignment class has make binary tree search using templates. had built integer binary search tree in previous class, same program few tweaks (the significant being templates). program made in previous class turned out working fine, after applying templates, gives me strange set of errors:
1>tester.obj : error lnk2019: unresolved external symbol "public: __thiscall bintree<int>::~bintree<int>(void)" (??1?$bintree@h@@qae@xz) referenced in function _main 1>tester.obj : error lnk2019: unresolved external symbol "public: void __thiscall bintree<int>::deletenode(int const &)" (?deletenode@?$bintree@h@@qaexabh@z) referenced in function _main 1>tester.obj : error lnk2019: unresolved external symbol "public: bool __thiscall bintree<int>::find(int const &)" (?find@?$bintree@h@@qae_nabh@z) referenced in function _main 1>tester.obj : error lnk2019: unresolved external symbol "public: int __thiscall bintree<int>::height(void)" (?height@?$bintree@h@@qaehxz) referenced in function _main 1>tester.obj : error lnk2019: unresolved external symbol "public: void __thiscall bintree<int>::postordertraversal(void)" (?postordertraversal@?$bintree@h@@qaexxz) referenced in function _main 1>tester.obj : error lnk2019: unresolved external symbol "public: void __thiscall bintree<int>::preordertraversal(void)" (?preordertraversal@?$bintree@h@@qaexxz) referenced in function _main 1>tester.obj : error lnk2019: unresolved external symbol "public: void __thiscall bintree<int>::inordertraversal(void)" (?inordertraversal@?$bintree@h@@qaexxz) referenced in function _main 1>tester.obj : error lnk2019: unresolved external symbol "public: void __thiscall bintree<int>::insert(int const &)" (?insert@?$bintree@h@@qaexabh@z) referenced in function _main 1>tester.obj : error lnk2019: unresolved external symbol "public: __thiscall bintree<int>::bintree<int>(void)" (??0?$bintree@h@@qae@xz) referenced in function _main my code broken between header of bts class, cpp file functions, , cpp tester.
bintree.h :
#pragma once #include <iostream> #include <string> using namespace std; //***** function described briefly in cpp file template<class t> class bintree { //the node struct struct btnode { t info; btnode* left; btnode* right; }; private: btnode* root; //the root void remove(btnode* &node); int heightrecursive(btnode *node); void destroyrecursive(btnode*); bool leaf(btnode* node) const; // recursive traversals void inorderrecursive(btnode* node); void preorderrecursive(btnode* node); void postorderrecursive(btnode* node); public: bintree(void); int height(); void insert(const t &indata); bool find (const t &indata); void deletenode(const t &indata); ~bintree(void); // traversal void inordertraversal(); void preordertraversal(); void postordertraversal(); }; bintree.cpp :
#include "bintree.h" //constructor, sets root equal null template<class t> bintree<t>::bintree(void) { root = null; } //inserts tree; if tree empty, inserts root // if tree has variable, outputs message , exits // other wise, search appropiate place fit variable in template<class t> void bintree<t>::insert(const t &indata) { btnode *newnode, *current, *parentofcurrent; newnode = new btnode; newnode->info = indata; newnode->left = newnode->right = null; if (root == null) { root = newnode; cout << "added root\n"; return; } current = root; while(current != null) { parentofcurrent = current; if(current->info == indata) { cout << indata << " exists in tree. duplicates not allowed!\n"; return; } else if(current->info > indata) current = current->left; else current = current->right; } if (parentofcurrent->info > indata) parentofcurrent->left = newnode; else parentofcurrent->right = newnode; } //--------------- inorder traversal ---------------------- //calls inordertraversal using root template <class t> void bintree<t>::inordertraversal() { if(root==null) cout << "empty tree\n"; else { inorderrecursive(root); cout << '\n'; } } //private variable, travels recursively in inorder accross tree, takes in btnode pointer template <class t> void bintree<t>::inorderrecursive(btnode* node) //left, node, right { if(node != null) { inorderrecursive(node->left); cout << node->info << ", "; inorderrecursive(node->right); } } //------------------ preorder traversal------------- //calls preordertraversal using root template <class t> void bintree<t>::preordertraversal() { if(root==null) cout << "empty tree\n"; else { preorderrecursive(root); cout << '\n'; } } //private variable, travels recursively in preorder accross tree, takes in btnode pointer template <class t> void bintree<t>::preorderrecursive(btnode* node) //node, left, right { if(node != null) { cout << node->info << ", "; preorderrecursive(node->left); preorderrecursive(node->right); } } //------------ postorder traversal----------------- //calls postordertraversal using root template <class t> void bintree<t>::postordertraversal() { if(root==null) cout << "empty tree\n"; else { postorderrecursive(root); cout << '\n'; } } //private variable, travels recursively in postorder accross tree, takes in btnode pointer template <class t> void bintree<t>::postorderrecursive(btnode* node) { if(node != null) { postorderrecursive(node->left); postorderrecursive(node->right); cout << node->info << ", "; } } //------- //searches tree , returns either true or false if found or not found template<class t> bool bintree<t>::find(const t &indata) { bool rv = false; btnode *current; if(root == null) return rv; current = root; while(current != null && rv == false) { if (current->info == indata) rv = true; else if (current->info > indata) current = current->left; else current = current->right; } return rv; } //deletes node using remove function. if tree empty or variable // not found, send message , abort. template <class t> void bintree<t>::deletenode(const t &indata) { btnode *current, *parentofcurrent; bool found = false; if (root == null) { cout << "the tree empty, aborting..."; return; } current = root; while(current != null) { if(current->info == indata) { found = true; break; } else { parentofcurrent = current; if(current->info > indata) current = current->left; else current = current->right; } } if(!found) cout << "\n" <<indata << " not found. aborting...\n"; else if (current == root) remove(root); else if (parentofcurrent->info > indata) remove(parentofcurrent->left); else remove(parentofcurrent->right); } // template <class t> void bintree<t>::remove(btnode* &node) // parent's node address of //node deleted. sent in ref. parent's node changed here { btnode *current, *parentofcurrent, *temp; if(node==null) { cout << "\ncannot delete null node.\n"; return; //the return here because if node null, technically leaf } else if(leaf(node) == true) //node leaf { temp = node; node = null; delete temp; } else cout << "\nnode not leaf, cannot delete.\n"; } //finds height of tree passing root heightrecursive function template <class t> int bintree<t>::height() { return heightrecursive(root); } //recursively travels tree , keeps counter each time encounters node template <class t> int bintree<t>::heightrecursive(btnode* node) { if (node == null) return 0; else return ( 1 + max(heightrecursive(node->left), heightrecursive(node->right))); } //destryuuctor; calls destroyrecursive function using root template <class t> bintree<t>::~bintree(void) { destroyrecursive(root); } //travels tree recursively, deleting every non-null encounters template <class t> void bintree<t>::destroyrecursive(btnode* node) { if(node != null) { destroyrecursive(node->left); destroyrecursive(node->right); delete node; node = null; } } //checks if node passed argument leaf, returns true or false template <class t> bool bintree<t>::leaf(btnode* node) const { bool aleaf = false; if(node->left == null && node->right == null) aleaf = true; return aleaf; } tester.cpp :
#include "bintree.h" int main() { bintree<int> example; int arr[] = { 75,43,77,29,52,82,35,56,79,32,40,90,48,47 }; //inserts array of integers tree for(int i=0; < 14; i++) example.insert(arr[i]); //---------------displays tree before changes------------------- cout << "in order traversal:\n"; example.inordertraversal(); cout << "pre-order traversal:\n"; example.preordertraversal(); cout << "post-order traversal:\n"; example.postordertraversal(); cout << "------------------displays tree after changes---------------------\n"; example.insert(21); cout << "\n------- inorder --------\n"; example.inordertraversal(); cout << "\n------- preorder --------\n"; example.preordertraversal(); cout << "\n------- postorder --------\n"; example.postordertraversal(); cout << "\nheight=" << example.height() << endl<<endl; //tests find function if (example.find(9)) cout << "found 9\n"; else cout << "9 not found\n"; if (example.find(77)) cout << "found 77\n"; else cout << "77 not found\n"; //tests delete function trying delete integer not in tree example.deletenode(122); //test insert inserting existent integer example.insert(77); //tests delete function deleting 77 example.deletenode(77); cout << "\nafter deleting 77 (inorder)\n"; example.inordertraversal(); system("pause"); //don't worry, system call gone in final submission return 0; } as said before, i'm sure has did wrong template implementation. if templates, can exact code fragment , should implemented? new templates, it's making head hurt bit. if helps, use visual studios 2010.
thanks, guys, appreciated!
here have why won't work: splitting templated c++ classes .hpp/.cpp files--is possible?
tl;dr: cannot split template class between .h , .cpp files, move implementation .h file.
Comments
Post a Comment