Tejas Srinivasan
Tejas Srinivasan

Reputation: 63

Undefined reference to inherited function

I am implementing the A* algorithm for solving a couple of problems - the 8 Puzzle problem and another one. For the A Star, I implemented three generic classes in A_star.hpp:

template <class U>
class Heuristic{
public:
    virtual int getHeuristic(Node<U> currNode, Node<U> target);
};

template <class V>
class NextNodeGenerator{
public:
    virtual vector<pair<V, int> > generate(Node<V> curr);
};

template <class W>
class CompareVal{
public:
    virtual bool compare(W val1, W val2);
};

For solving the 8 Puzzle problem, I implemented three child classes in a prob2.cpp for each of the above generic classes:

template <class hT>
class PuzzleHeuristic: public Heuristic<hT>{
public:
    virtual int getHeuristic(Node<hT> currNode, Node<hT> target){
        //Code for getHeuristic
    }
};

template <class cT>
class PuzzleCompareVal: public CompareVal<cT>{
public:
    virtual bool compare(cT val1, cT val2){
        //Code for compare
    }
};

template <class nT>
class PuzzleNNG: public NextNodeGenerator<nT>{
public:
    virtual vector<pair<nT, int> > generate(Node<nT> curr){
        //Code for generate
}

In A_star.hpp, I also had an AStar class:

template <class Y>
class AStar{
    Heuristic<Y> *h;
    NextNodeGenerator<Y> *nng;
    CompareVal<Y> *comp;

public:

    void setHeuristic(Heuristic<Y> *hParam){
        h = hParam;
    }

    void setNNG(NextNodeGenerator<Y> *nngParam){
        nng = nngParam;
    }

    void setCompareVal(CompareVal<Y> *compParam){
        comp = compParam;
    }

    vector<Node<Y> > solve(Y start, Y target){
        //Code for solve
    }

In my main() function in prob2.cpp, I had created an AStar object (Array is a template class I'd defined separately):

int main()
{
    PuzzleHeuristic<Array<int> > pH;
    PuzzleCompareVal<Array<int> > pCV;
    PuzzleNNG<Array<int> > pNNG;

    AStar<Array<int> > aStar;
    aStar.setHeuristic(&pH);
    aStar.setNNG(&pNNG);
    aStar.setCompareVal(&pCV);

    vector<Node<Array<int> > > answer = aStar.solve(start, target);
}

On compiling, I got the following error:

/tmp/ccCLm8Gn.o:(.rodata._ZTV17NextNodeGeneratorI5ArrayIiEE[_ZTV17NextNodeGeneratorI5ArrayIiEE]+0x10): undefined reference to NextNodeGenerator<Array<int> >::generate(Node<Array<int> >)' /tmp/ccCLm8Gn.o:(.rodata._ZTV10CompareValI5ArrayIiEE[_ZTV10CompareValI5ArrayIiEE]+0x10): undefined reference toCompareVal >::compare(Array, Array)' /tmp/ccCLm8Gn.o:(.rodata._ZTV9HeuristicI5ArrayIiEE[_ZTV9HeuristicI5ArrayIiEE]+0x10): undefined reference to `Heuristic >::getHeuristic(Node >, Node >)' collect2: error: ld returned 1 exit status Blockquote

I suspect the problem is due to the inheritance in template functions. What could be causing the error?

Upvotes: 2

Views: 3000

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409166

All virtual functions need a definition, even if they are overridden in the child classes. If you don't want to implement them in the base class, and force the child-classes to override the functions you should make them abstract in the base class, for example like

template <class V>
class NextNodeGenerator{
public:
    virtual vector<pair<V, int> > generate(Node<V> curr) = 0;
    //                                                  ^^^^
    //   This is what makes the function an abstract function 
};

Upvotes: 5

Related Questions