I'm trying to set up a couple classes, but I'm getting an error: Linker error - Undefined reference to 'Node::~Node()'. I think it might have something to do with how my headers are set up, but I'm unsure what I need to do to fix it. (FYI I added using std to try to fix some other problems, although it's not necessary).

Thanks.

Line.h

#ifndef LINE_H
#define LINE_H
#include "Node.h"
using namespace std;

class Line
{
    public:
        double m; //slope
        double b; //y-int
        
        Line(Node p, Node q)
        {
            m = ((double)(p.r-q.r))/((double)(p.c-q.c));
            b = p.r-(m*q.c);
        }
        
        double getr(int c)
        {
            return m*c+b;
        }
        
        double getc(int r)
        {
            return (r-b)/m;
        }
        
        ~Line();
        
};
#endif

Node.h

#ifndef NODE_H
#define NODE_H
#include <vector>
using namespace std;

class Node
{
    public:
        int status; //process status
        int r,c; //xy coords

        vector<Node> neighbors; //list of neighbors
        vector<double> distances; //distance between this node and node in neighbors.at(i)
        
        Node(void)
        {
            r = 0;
            c = 0;
            status = 0;
        }
        
        Node(int newr, int newc)
        {
            r = newr;
            c = newc;
            status = 0;
        }
        
        void add(Node newneighbor,double dist)
        {
            neighbors.push_back(newneighbor);
            distances.push_back(dist);
        }
        
        ~Node();
};
#endif

Driver.cpp

#include <iostream>
#include <vector>
#include <math.h>

#include "Node.h"
#include "Line.h"

using namespace std;

Node find(char c); //search grid for character c and return a node with grid coordinates
bool isCorner(int r, int c, int newr, int newc); //test if cell (newr,newc) is an empty corner of cell (r,c)
bool isFree(double r, double c); //test if cells containing (r,c) are empty
bool validLine(Node a, Node b); //test whether a line can be drawn from node a to node b without intersecting walls
void link(Node a, Node b, double dist); //link two nodes together with a distance dist
double dist_form(Node a, Node b); //distance between two nodes
bool isValid(double r, double c); //test if intersecting cells of point (r,c) are empty

int G_ROWS = 6;
int G_COLS = 10;
char* grid[] = {"          ",
                   "    #     ",
                   "    #     ",
                   " s  #  e  ",
                   "    #     ",
                   "          "};

Node start = find('s');
Node end = find('e');

//stores all nodes
vector<Node> graph;

int main()
{
    graph.push_back(start);
    //create nodes
    for (int r=0; r<G_ROWS; r++)
        for (int c=0; c<G_COLS; c++)
        {
            if (isCorner(r,c,r+1,c+1))
                graph.push_back(Node(r+1,c+1));
            if (isCorner(r,c,r+1,c-1))
                graph.push_back(Node(r+1,c));
            if (isCorner(r,c,r-1,c+1))
                graph.push_back(Node(r,c+1));
            if (isCorner(r,c,r-1,c-1))
                graph.push_back(Node(r,c));
        }
    graph.push_back(end);
    
    //link nodes
    for (int i=0; i<graph.size()-1; i++)
        for (int j=i+1; j<graph.size(); j++)
            if (validLine(graph.at(i),graph.at(j)))
                link(graph.at(i),graph.at(j),dist_form(graph.at(i),graph.at(j)));
    
    //print out data
    for (int i=0; i<graph.size(); i++)
        cout << " " << graph.at(i).r << ", " << graph.at(i).c << "\n";
    
    system("pause");
    return 0;
}

//finds the first cell with value c and returns the node of that cell
Node find(char c)
{
    for (int r=0; r<G_ROWS; r++)
        for (int c=0; c<G_COLS; c++)
            if (grid[r][c]==c) return(Node(r,c));
    return (Node(-1,-1));
}

//test whether cell (newr,newc) is an empty corner of cell (r,c)
bool isCorner(int r, int c, int newr, int newc)
{
    //check boundaries
    if (newr<0 || newr>=G_ROWS || newc<0 || newc>=G_COLS) return false;
    
    if (grid[newr][newc]!=' ') return false;
    //check if valid corner location
    int difr = r-newr;
    int difc = c-newc;
    if (abs(difr)!=1 || abs(difc)!=1) return false;
    
    //test bordering cells
    return (grid[newr+difr][newc]==' ' && grid[newr][newc+difc]==' ');
}


//test if cells that contain point (r,c) are empty
bool isFree(double r, double c)
{
    for (double newr=r; int(newr)>=0; newr--)
        for (double newc=c; int(newc)>=0; newc--)
            if (grid[int(newr)][int(newc)]!=' ') return false;
    return true;
}

//test if nodes are valid neighbors (aka: line can be drawn between them
bool validLine(Node a, Node b)
{
    //find line to place points on
    Line myLine(a,b);
    
    for (int i=min(a.c,b.c); i<max(a.c,b.c); i++)
        if (!isValid(i,myLine.getc(i))) return false;
    
    for (int i=min(a.r,b.r); i<max(a.r,b.r); i++)
        if (!isValid(myLine.getr(i),i)) return false;
        
    return true;
}

//link two nodes togethr as neighbors with distance dist
void link(Node a, Node b, double dist)
{
    a.add(b,dist);
    b.add(a,dist);
}

double dist_form(Node a, Node b)
{
    return sqrt(pow(a.c-b.c,2) + pow(a.r-b.r,2));
}

//test is intersecting cells of (r,c) are empty
bool isValid(double r, double c)
{
    for (double newr=r; int(newr)>=0; newr--)
        for (double newc=c; int(newc)>=0; newc--)
            if (grid[int(newr)][int(newc)]!=' ') return false;
    return true;
}

The error message says it all -- the Node class has a destructor but the implementation for it was never coded.

You can remove the destructor; ~Node(); since you are not implementating it. In this case, the compiler actually generates the default destructor for you. However, if you want to customize your destructor, do add in your implementation as in:

~Node()
{
        // your code goes here
}

My fault. I had previously tried implementing the destructor (~Node(){}) but it was still failing. I ran a cleanup and it now compiles. And thanks for the info!

Please set the thread to resolved so that others know the solution has been found for this problem. Thanks!

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.