0

I'm having trouble wrapping my head around why this code is not compiling. I am implementing a stack as a doubly linked list. I cannot get my AddToHead() to work. More specifically, the program wont compile if I try to dynamically create a CharNode object. I thought by having #include "charlist.h" would give the program access to the CharNode class, since it resides in charlist.h

I compile with: g++ -ansi -pedantic -Wall charlist.cxx -o clist

This is the error I get:

/tmp/ccHzaOmz.o: In function `CharList::AddToHead(char)':
charlist.cxx:(.text+0xe9): undefined reference to `CharNode::CharNode(char, CharNode*, CharNode*)'
collect2: error: ld returned 1 exit status

I know that undefined reference means that the CharNode resources can't be found by the linker. I just don't know why it is happening here.

Here is charlist.h

#ifndef __CharList__
#define __CharList__

#include <iostream>
#include <string>

using namespace std;

class CharList;

//CharNode class is clearly here in charlist.h
class CharNode
{
private:
    char value;
    CharNode* prev;
    CharNode* next;
public:
    CharNode(char value, CharNode* prev = NULL, CharNode* next = NULL);
    friend class CharList;
};

class CharList
{
private:
    CharNode* h;
    CharNode* t;
public:
    CharList();
    ~CharList();
    bool IsEmpty() const;
    char GetHead() const; //FUNCTION CAUSING ERROR
    char GetTail() const;
    void AddToHead(char v);
    void AddToTail(char v);
};

#endif //__CharList__

Here is charlist.cxx

#include <iostream>
#include <string>
#include <sstream>
#include <cassert>
#include <stdlib.h>
#include "charlist.h"

using namespace std;

CharList::CharList()
{
    h = t = NULL;
}

bool CharList::IsEmpty() const
{
    return (h == NULL);
}
//All other member functions excluded for relevancy 

void CharList::AddToHead(char v){
    CharNode* newHead;
    newHead = new CharNode(v); //Why cant I do this? Error Line.
    newHead->prev = NULL;
    newHead->next = h;

    if (IsEmpty()){
        t = newHead;
        h = newHead;
    } else {
        h->prev = newHead;
        h = newHead;
    }
}
  • 1
    Regarding `__CharList__`: [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier). Also `using namespace std;` [is not recommended](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice), but placing it in a header can turn the header into a boobytrap for the unwary. – user4581301 Oct 30 '18 at 02:45

2 Answers2

2

Below, you have a declaration of a constructor. This is a promise that you will define a constructor, somewhere.

CharNode(char value, CharNode* prev = NULL, CharNode* next = NULL);

Change it to also include the definition, and you will not get that undefined error.

CharNode(char value, CharNode* prev = NULL, CharNode* next = NULL)
    : value(value)
    , prev(prev)
    , next(next)
{
}
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
0

Because you have not defined CharNode::CharNode() anywhere yet.

Fill in the following in your charlist.cxx and it should build and link:

CharNode::CharNode(char value, CharNode* prev = NULL, CharNode* next = NULL)
{
  // Your code here...
}
tdk001
  • 1,014
  • 1
  • 9
  • 16