2016-04-09 16 views
0

Ich implementiere den A * -Algorithmus zur Lösung ein paar Probleme - das 8-Puzzle-Problem und ein anderes. Für die A Star, ich implementiert drei generische Klassen in A_star.hpp:Undefinierter Verweis auf geerbte Funktion

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); 
}; 

für das 8-Puzzle Problem zu lösen, implementiert ich drei Kind-Klassen in einem prob2.cpp für jede der oben genannten generischen Klassen:

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, habe ich auch eine AStar Klasse hatte:

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 meiner Funktion main() in prob2.cpp hatte ich ein AStar Objekt (Array ist eine Template-Klasse habe ich definiert hatte getrennt):

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); 
} 

zum Kompilieren, bekam ich folgende Fehlermeldung:

/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 to CompareVal >::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

Ich vermute, dass das Problem auf die Vererbung in Template-Funktionen zurückzuführen ist. Was könnte den Fehler verursachen?

Antwort

2

Alle virtuellen Funktionen benötigen eine Definition, auch wenn sie in den untergeordneten Klassen überschrieben werden. Wenn Sie sie in der Basisklasse nicht implementieren möchten, und die Kinder Klassen zwingen, um die Funktionen außer Kraft setzen, sollten Sie sie abstrakte in der Basisklasse machen, zum Beispiel wie

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 
}; 
Verwandte Themen