Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

C++ Pleased help me I am learning code am struggling with a class constructor undefined reference error

ScooterDooter

New Coder
I am trying to get a .cpp .h header file working with a large program who's code otherwise works. I feel as if i am close but keep getting an error related to my ResearchPlan class' constructor i thing i have my variable types wrong or i set up my iterators wrong im not sure. the error message i get when ever the constructor is calleds upon is "undefined reference to 'ResearchPlan::ResearchPlan<Topic*>(Topic const&, Topic , Topic)'" , the declairaition for this constructor is
"ResearchPlan (Topic const& topic, const Iterator startR, const Iterator stopR);". Im sorry if this is the wrong way to ask for help but im running out of steam on this one.




here is picture of everything including the build terminal

To view this content we will need your consent to set third party cookies.
For more detailed information, see our cookies page.
.cpp file
-----------------------
Code:
using namespace std;
using namespace std::rel_ops;

/// Iterators
ResearchPlan::iterator ResearchPlan::begin()
{
    return requirements.begin();
}
ResearchPlan::const_iterator ResearchPlan::begin() const
{
    return requirements.begin();
}
ResearchPlan::iterator ResearchPlan::end()
{
    return requirements.end();
}
ResearchPlan::const_iterator ResearchPlan::end() const
{
    return requirements.end();
}

/// Overloaded Operators
bool ResearchPlan::operator== (const ResearchPlan& right) const
{
    using namespace std::rel_ops;
    if (researchTopic != right.researchTopic)
        return false;
if (requirements.size() == right.requirements.size())
    {
      const node<Topic>* current = first;
      const node<Topic>* bcurrent = right.first;
      while (current != nullptr)
        {
          if (!(current->nodeValue == bcurrent->nodeValue))
            return false;
          current = current->next;
          bcurrent = bcurrent->next;
        }
      return true;
    }
  else
    return false;
}
bool ResearchPlan::operator!= (const ResearchPlan& right) const
{
    using namespace std::rel_ops;

    if (researchTopic == right.researchTopic)
        return false;
    if (requirements.size() == right.requirements.size())
    {
      const node<Topic>* current = first;
      const node<Topic>* bcurrent = right.first;
      while (current != nullptr)
        {
          if (current->nodeValue == bcurrent->nodeValue)
            return false;
          current = current->next;
          bcurrent = bcurrent->next;
        }
      return true;
    }
  else
    return false;
}
bool ResearchPlan::operator< (const ResearchPlan& right) const
{
    using namespace std::rel_ops;

    if (researchTopic != right.researchTopic)
        return researchTopic < right.researchTopic;

if (requirements.size() == right.requirements.size())
    {
      const node<Topic>* current = first;
      const node<Topic>* bcurrent = right.first;
      while (current != nullptr)
        {
          if (!(current->nodeValue == bcurrent->nodeValue))
            return false;
          current = current->next;
          bcurrent = bcurrent->next;
        }
      return true;
    }
  else
    return false;

}

/// Constructors
ResearchPlan::ResearchPlan()
: researchTopic()
{
    
}

ResearchPlan::ResearchPlan (const Topic& topic)
:researchTopic(topic)
{
    
}

template <typename Iterator>
ResearchPlan::ResearchPlan (Topic const& topic, const Iterator startR, const Iterator stopR)
{
    researchTopic = topic;
    requirements= (startR,stopR);
     node<Topic>* first=startR;
     node<Topic>* last=stopR;
}


/// Functions
ResearchPlan::ResearchPlan (const ResearchPlan& b)
: researchTopic(b.researchTopic), first(nullptr), last(nullptr)
{
    for (node<Topic>* p = b.first; p != nullptr; p=p->next)
       addRequirement(p->nodeValue);
}
const ResearchPlan& ResearchPlan::operator= (const ResearchPlan& b)
{
    if (this != &b)
    {
       researchTopic = b.researchTopic;
       clear();
       for (node<Topic>* p = b.first; p != nullptr; p = p->next)
         addRequirement(p->nodeValue);
    }
    return *this;
}

void ResearchPlan::clear()
{
    node<Topic>* next = nullptr;
    for (node<Topic>* current = first; current != nullptr; current = next)
    {
        next = current->next;
        delete current;
    }
    first = last = nullptr;
}

ResearchPlan::~ResearchPlan()
{
    clear();
}

void ResearchPlan::addRequirement(const Topic& topic)
{
      node<Topic>* newNode = new node<Topic>(topic, nullptr);
  if (first == nullptr)
    {
      first = newNode;
    }
  else
    {
      // Move to last node
      node<Topic>* current = first;
      while (current->next != nullptr)
        current = current->next;
        //current->next = newNode;
      }
}

void ResearchPlan::removeRequirement(const Topic& au)
{
  node<Topic>* prev = nullptr;
  node<Topic>* current = first;
  while (current != nullptr && current->nodeValue.name != au.name )
  {
   prev = current;
   current = current->next;
  }
  if (current != nullptr)
  {
    // We found the author we were looking for.
    if (prev == nullptr)
      {
       // We are removing the first node in the list
       first = current->next;       
       delete current;
      }
    else
      removeAfter (prev);
  }
}
void ResearchPlan::removeAfter (node<Topic>* afterThis)
{
  node<Topic>* toRemove = afterThis->next;
  afterThis->next = toRemove->next;
  delete toRemove;
}


std::ostream& operator<< (std::ostream& out, const ResearchPlan& plan)
{
    return (out);
}

.h file
-------------

Code:
#ifndef RESEARCHPLAN_H
#define RESEARCHPLAN_H

#include <iostream>
#include <string>
#include <list>
#include "topic.h"
#include <iterator>
using namespace std;
///Node class
template <typename T>
class node {
public:
   const T nodeValue;
   node<T>* next;

   node() : next(nullptr)
   {}

   node (const T& item, node<T>* nextNode = nullptr)
     : nodeValue(item), next(nextNode)
   {}

};
/**
 * A ResearchPlan describes the prior requirements for researching
 * a research topic.  It consists of a topic to be researched and a list of
 * research requirements, prior topics that must have been successfully
 * completed before research on this one can begin.
 */

class ResearchPlan {
    //** See the assignment page for required changes to
    //** these private declarations.
    Topic researchTopic;           ///< The topic to be researched
    
public:
    ///iterators & Nodes
    typedef list<Topic>::iterator iterator;
    typedef list<Topic>::const_iterator const_iterator;
    std::list<Topic> requirements;
    
    iterator begin();
    const_iterator begin() const;
    iterator end();
    const_iterator end() const;

    node<Topic>* first;
    node<Topic>* last;

    ///Overloaded Operatorsas
    bool operator== (const ResearchPlan& right) const;
    bool operator!= (const ResearchPlan& right) const;
    bool operator< (const ResearchPlan& right) const;

    /// Research Plan Constructor
    ResearchPlan();

    ResearchPlan (const Topic& topic);

    template <typename Iterator>
    ResearchPlan (const Topic& topic, const Iterator startR, const Iterator stopR);
    




    ///ResearchPlan Functions
    ResearchPlan (const ResearchPlan& b);  ///Copy
    const ResearchPlan& operator= (const ResearchPlan& b); ///Copy

    void clear(); ///Destruct
    ~ResearchPlan(); ///Destruct

    void addRequirement(const Topic& topic);
        /**
         * Add
 
Man, I feel your pain... Stuff like this reminds me again why I hate C++. I tip my hat to anyone who can make sense of these horrific error messages.

If you look closely, you see that these are linker error messages. All cpp sources have been compiled successfully, but the linker found two references to ResearchPlan constructors in testResearchPlan.cpp that it cannot resolve. Are these constructors supposed to be found in recearchplan.cpp as the name suggests ? Can you check if researchplan.o has these specific functions exported ?
My Unix is getting a little rusty from disuse over time but I seem to remember you can check that with the nm command.

Just thinking out loud really... I'm not at all sure I can help you along.

BTW - It would have been better if you had posted your make output as text (in a Code tag) instead of an image. Screenshots of text are generally not a good idea.
 
I am trying to get a .cpp .h header file working with a large program who's code otherwise works. I feel as if i am close but keep getting an error related to my ResearchPlan class' constructor i thing i have my variable types wrong or i set up my iterators wrong im not sure. the error message i get when ever the constructor is calleds upon is "undefined reference to 'ResearchPlan::ResearchPlan<Topic*>(Topic const&, Topic , Topic)'" , the declairaition for this constructor is
"ResearchPlan (Topic const& topic, const Iterator startR, const Iterator stopR);". Im sorry if this is the wrong way to ask for help but im running out of steam on this one.

Probably you fixed it already, but if someone else run into a similar problem:

Template functions don't have external linkage. That means, that they are not exposed from the cpp file. If you then want to use the function in a different .cpp file, the linker cannot find it.
To fix it, the impelementation must be provided in the .h file. Then the linker sees it from every .cpp file where the .h file is included.
 

New Threads

Latest posts

Buy us a coffee!

Back
Top Bottom