Alright so my problem is I am getting an error that says undefined reference to all of my functions related to DoubleLinked, DoubleLinked<string> dict, dict.add, etc. If anyone knows why that would be great. Thank you. Oh and if i add () to DoubleLinked<string> dict then i just have undefined reference errors to add and contains.

#include <iostream>
#include "DoubleLinked.h"
#include "Node.h"
#include <fstream>
#include <vector>
using namespace std;


int main()
{
    cout << "Hello" << endl;
    string st = "hello";
    DoubleLinked<string> dict;

   vector <string> phrase;
   vector <string> Wrong;
   dict.add(st);
   ifstream fin;
   fin.open("check.txt");
   string word;
   int c = 0;
   while(fin >> word && c < phrase.size() )
   {
        phrase[c] == word;
        c++;
   }
   fin.close();
   int count = 0;
   for(int i = 0; i < phrase.size(); i++)
   {
       string str = phrase[i];
       if(!dict.contains(str))
       {
            Wrong[count] = phrase[i];
            count++;
       }
   }
   cout<<"The following words are spelled incorrectly: " <<endl;
   for(int i = 0; i < Wrong.size(); i++)
        cout << Wrong[i];

   return 0;
}




#include "DoubleLinked.h"
#include "Node.h"
#include <cstddef>

template<class ItemType>
DoubleLinked<ItemType>::DoubleLinked() : headPtr(NULL), itemCount(0)
{
}  // end default constructor

template<class ItemType>
DoubleLinked<ItemType>::DoubleLinked(const DoubleLinked<ItemType>& aBag)
{
    itemCount = aBag->itemCount;
   Node<ItemType>* origChainPtr = aBag->headPtr;  // Points to nodes in original chain

   if (origChainPtr == NULL)
      headPtr = NULL;  // Original bag is empty; so is copy
   else
   {
      // Copy first node
      headPtr = new Node<ItemType>();
      headPtr->setItem(origChainPtr->getItem());

      // Copy remaining nodes
      Node<ItemType>* newChainPtr = headPtr; // Last-node pointer
      while (origChainPtr != NULL)
      {
         origChainPtr = origChainPtr ->getNext(); // Advance pointer

         // Get next item from original chain
         ItemType nextItem = origChainPtr->getItem();

         // Create a new node containing the next item
         Node<ItemType>* newNodePtr = new Node<ItemType>(nextItem);

         // Link new node to end of new chain
         newChainPtr->setNext(newNodePtr);
         //link to last node
         newChainPtr->setPrev(origChainPtr);

         // Advance pointer to new last node
         newChainPtr = newChainPtr->getNext();
      } // end while

      newChainPtr->setNext(NULL); // Flag end of new chain
   } // end if
} // end copy constructor

template<class ItemType>
DoubleLinked<ItemType>::~DoubleLinked()
{
   clear();
}  // end destructor

template<class ItemType>
bool DoubleLinked<ItemType>::isEmpty() const
{
    return itemCount == 0;
}  // end isEmpty

template<class ItemType>
int DoubleLinked<ItemType>::getCurrentSize() const
{
    return itemCount;
}  // end getCurrentSize

template<class ItemType>
bool DoubleLinked<ItemType>::add(const ItemType& newEntry)
{
   Node<ItemType>* curr;
    curr = headPtr;
   // Add to beginning of chain: new node references rest of chain;
   // (headPtr is null if chain is empty)
   Node<ItemType>* nextNodePtr = new Node<ItemType>();
   nextNodePtr->setItem(newEntry);
   nextNodePtr->setNext(headPtr);// New node points to chain
   headPtr-> prev = curr;

//   Node<ItemType>* nextNodePtr = new Node<ItemType>(newEntry, headPtr); // alternate code

   headPtr = nextNodePtr;          // New node is now first node
   itemCount++;

   return true;
}  // end add

template<class ItemType>
vector<ItemType> DoubleLinked<ItemType>::toVector() const
{
   vector<ItemType> bagContents;
   Node<ItemType>* curPtr = headPtr;
   int counter = 0;
    while ((curPtr != NULL) && (counter < itemCount))
   {
        bagContents.push_back(curPtr->getItem());
      curPtr = curPtr->getNext();
      counter++;
   }  // end while

   return bagContents;
}  // end toVector

template<class ItemType>
bool DoubleLinked<ItemType>::remove(const ItemType& anEntry)
{
   Node<ItemType>* entryNodePtr = getPointerTo(anEntry);
   bool canRemoveItem = !isEmpty() && (entryNodePtr != NULL);
   if (canRemoveItem)
   {
      // Copy data from first node to located node
      entryNodePtr->setItem(headPtr->getItem());

      // Delete first node
      Node<ItemType>* nodeToDeletePtr = headPtr;
      headPtr = headPtr->getNext();

      // Return node to the system
      nodeToDeletePtr->setNext(NULL);
      delete nodeToDeletePtr;
      nodeToDeletePtr = NULL;

      itemCount--;
   } // end if

    return canRemoveItem;
}  // end remove

template<class ItemType>
void DoubleLinked<ItemType>::clear()
{
   Node<ItemType>* nodeToDeletePtr = headPtr;
   while (headPtr != NULL)
   {
      headPtr = headPtr->getNext();

      // Return node to the system
      nodeToDeletePtr->setNext(NULL);
      delete nodeToDeletePtr;

      nodeToDeletePtr = headPtr;
   }  // end while
   // headPtr is NULL; nodeToDeletePtr is NULL

    itemCount = 0;
}  // end clear

template<class ItemType>
int DoubleLinked<ItemType>::getFrequencyOf(const ItemType& anEntry) const
{
    int frequency = 0;
   int counter = 0;
   Node<ItemType>* curPtr = headPtr;
   while ((curPtr != NULL) && (counter < itemCount))
   {
      if (anEntry == curPtr->getItem())
      {
         frequency++;
      } // end if

      counter++;
      curPtr = curPtr->getNext();
   } // end while

    return frequency;
}  // end getFrequencyOf

template<class ItemType>
bool DoubleLinked<ItemType>::contains(const ItemType& anEntry) const
{
    return (getPointerTo(anEntry) != NULL);
}  // end contains

template<class ItemType>
Node<ItemType>* DoubleLinked<ItemType>::getPointerTo(const ItemType& anEntry) const
{
   bool found = false;
   Node<ItemType>* curPtr = headPtr;

   while (!found && (curPtr != NULL))
   {
      if (anEntry == curPtr->getItem())
         found = true;
      else
         curPtr = curPtr->getNext();
   } // end while

   return curPtr;
} // end getPointerTo

Recommended Answers

All 13 Replies

string has not been defined. You need to include <string> header file. Some compilers do that for you while others do not, so it's best to just get into the habit of always including <string> if you use it.

The problem here is that you cannot separate the definition and declaration of templates (class or functions). You have to understand that template code is not "real" code, it is a set of precise instructions for the compiler about what code to generate once the template argument(s) have been provided. Since source files are compiled separately (in isolation from each other), you cannot put the definitions (implementations) of the function templates in a separate cpp file, that is, one that is different from the cpp file in which the template is used (with some argument(s)). This is why you get all these errors. The cpp file in which the main() function appears, in which the class template is being used, does not contain any of the implementation code of that class template. So, the compiler cannot generate code for that specific instantiation of the class template, so it is left to assume that there was one already compiled (in another object file). At this point, the linker takes over and tries to find the definitions of those functions. However, when you compiled the other cpp file (with the definitions of the function templates), there was no instantiation of that class template, so no "real" code to compile, so, nothing to be found by the linker, and hence, the avalanche of "undefined reference" errors (which means the linker didn't find what it was looking for).

So, long story short, the definitions (implementations) of you class template's member functions must appear in the header file. That's just the way it is (there are a few tricks to get around this, but they're a bit tricky and limited). Here's another helpful read.

Alright so i added string header file and that saddly did nothing. And mike I think I understand what you mean and I did that and it did not help. I have a header file declaring all of these functions, I did not include that because I fifgured I would not need to.

Post both header files so that we can try to compile it. If they are pretty big you might want to zip them up and attach them to your post.

Will do. Thank you for al the help so far.

Here are the files

Need BagInterface.h

That might be the problem right there. I dont think I included that. But here the file is just in case

I compiled it with Visual Studio 2012 and got these unresolved externals, which means you have not implemented some of the functions in that template.

1>SpellCheckMain.obj : error LNK2019: unresolved external symbol "public: __thiscall DoubleLinked<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::DoubleLinked<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" (??0?$DoubleLinked@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAE@XZ) referenced in function _main
1>SpellCheckMain.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall DoubleLinked<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::~DoubleLinked<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" (??1?$DoubleLinked@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@UAE@XZ) referenced in function _main
1>SpellCheckMain.obj : error LNK2019: unresolved external symbol "public: virtual bool __thiscall DoubleLinked<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::add(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?add@?$DoubleLinked@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@UAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main
1>SpellCheckMain.obj : error LNK2019: unresolved external symbol "public: virtual bool __thiscall DoubleLinked<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::contains(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)const " (?contains@?$DoubleLinked@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@UBE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main
1>C:\dvlp\ConsoleApplication3\Debug\ConsoleApplication3.exe : fatal error LNK1120: 4 unresolved externals

I checked to see if any were unimplemented and I did not see any but I did look through it fast. I will check again later.

You must move the contents of DoubleLinked.cpp into DoubleLinked.h, and move the contents of Node.cpp into Node.h. As I said, you cannot have the function definitions in a separate cpp file, they must be in the header file.

alright. so i fixed that problem but now there is a new one. there is somthing wrong with my add function. it does not add at all. i also had to comment out the line headPtr-> setPrev(curr);. I check after i use add function with isEmpty() and that returned true.

Nevermind I lied about that.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.