2012-05-09 2 views
0

Я пишу двоичное дерево поиска с использованием шаблонов. Идея состоит в том, что у меня есть чистый абстрактный базовый класс с функциями перегрузки виртуальных операторов, которые используются для сравнения с другими классами, которые наследуют его одного типа. Этот класс, или, скорее, любой класс, который наследует от него, представляет собой «ключ» в BST.Ошибки шаблона: нерешенные внешние и внутренние классы друзей

Хорошим примером является то, что я планирую сделать с этим в начале, которое добавляет источники шейдеров (в строках, обработанных из файлов шейдеров) в значения BST как значения, причем ключ является типом ShaderComparable, который содержит имя файла шейдера и используется для сравнения ключей в BST.

Проблема заключается в том, что, когда я писал код, он скомпилировал бы отлично, как только я вставлю экземпляр класса BST в main и попытаюсь запустить его, я получаю ссылки «нерешенные внешние» ошибки.

Код

SearchTree.hpp

#pragma once 

#include <stdint.h> 
#include "Comparable.hpp" 

namespace esc 
{ 
    /* 
    * NOTE: K must inherit from type 'Comparable', located in "Comparable.hpp" 
    */ 

    template < typename TComparable, typename TValue > 
    class SearchTree 
    { 
    public: 
     class Iterator; 
    private: 
     struct Node; 
     typedef typename Node TNode; 
    public: 
     SearchTree(void); 
     ~SearchTree(void); 
    public: 
     //TValue find(const TComparable& k); 
     //TValue find(int32_t index); 
     //TValue find(const Iterator& pIter); 

     //Iterator begin(void) const; 
     //Iterator end(void) const; 

     void insert(const TComparable& k, const TValue& v); 
     //void insert(const Iterator& pIter); 

     friend class Iterator; 
    private: 
     int32_t mNodeCount; 
     TNode* mRoot; 
    public: 
     class Iterator 
     { 
     public: 
      Iterator(void); 
      inline TNode* operator->(void) const 
      { return mCurrentNode; } 
     private: 
      ~Iterator(void); 
      int32_t getNumStepsLeftToLeaf(void); 
      int32_t getNumStepsRightToLeaf(void); 
      void tallyDirectionalComparison(int& numLeftTrue, int& numRightTrue, const TComparable& k); 
      void insertLeft(const TComparable& k, const TValue& v); 
      void insertRight(const TComparable& k, const TValue& v); 
      bool isLeafNode(const Node*& a); 
      bool isInternalNode(const Node*& node); 
     private: 
      TNode* mCurrentNode; 
      int32_t mIterPosition; 
      friend class Node; 
     }; 
    private: 
     struct Node 
     { 
     public: 
      int32_t index; 
      TComparable Key; 
      TValue Value; 
     private: 
      TNode* mParent; 
      TNode* mLeftChild; 
      TNode* mRightChild; 
     }; 
    }; 
} 

SearchTree.cpp

template < typename TComparable, typename TValue > 
    SearchTree< TComparable, TValue >::SearchTree(void) 
     : mRoot(NULL), 
      mPosition(0), 
      mNodeCount(0) 
    {} 

    template < typename TComparable, typename TValue > 
    SearchTree< TComparable, TValue >::~SearchTree(void) 
    { 
     //TODO 
    } 

Там больше кода в источнике, я просто не хотел, чтобы получить возможность отправлять все это, в надежде избежать двусмысленности. Определения итератора, как правило, что-то вдоль линий этого:

template < typename TComparable, typename TValue > 
void SearchTree< TComparable, TValue >::Iterator::insertRight(const TComparable& k, const TValue& v) 

т.д.

Ошибки

1>Main.obj : error LNK2019: unresolved external symbol "public: __thiscall esc::SearchTree<class esc::ShaderComparable,struct esc::Shader>::~SearchTree<class esc::ShaderComparable,struct esc::Shader>(void)" ([email protected]@[email protected]@[email protected]@@[email protected]@[email protected]) referenced in function _main 

1>Main.obj : error LNK2019: unresolved external symbol "public: __thiscall esc::SearchTree<class esc::ShaderComparable,struct esc::Shader>::SearchTree<class esc::ShaderComparable,struct esc::Shader>(void)" ([email protected]@[email protected]@[email protected]@@[email protected]@[email protected]) referenced in function _main 

Вопрос

Почему я получаю эти ошибки? Что я могу сделать, чтобы остановить их?

ответ

0

Я предполагаю, что это связано с тем, что вы сделали некоторые из ваших деструкторов частными. Попробуйте сделать их общедоступными.

0

Элементы функций члена шаблона класса должны находиться в заголовке (SearchTree.hpp), а не в .cpp-файле. См. here для канонического ответа стека переполнения.

+0

Итак, я не могу записать их в исходном файле? – zeboidlund

Смежные вопросы