2015-05-03 12 views
0

Моя структура кода выглядит следующим образом. У меня есть базовый абстрактный класс, который также имеет вложенный абстрактный итератор. Я наследую от базового класса, и я также наследую от абстрактного базового унаследованного класса. Для того, чтобы выделить объекты, которые я использую полиморфизм:Абстрактный базовый класс имеет абстрактный вложенный класс

я получаю ошибки типа:

In file included from newDataStore.h:6:0, 
        from newDataStore.cpp:1: 
    ../HashTable/baseHashTable.h: In instantiation of ‘class BaseHashTable<std::basic_string<char>, User*>::iterator’: 
    ../HashTable/hashTable.h:53:8: required from ‘class HashTable<std::basic_string<char>, User*>::iterator’ 
    ../HashTable/hashTable.h:8:7: required from ‘class HashTable<std::basic_string<char>, User*>’ 
    newDataStore.cpp:10:25: required from here 
    ../HashTable/baseHashTable.h:59:19: error: cannot allocate an object of abstract type ‘BaseHashTable<std::basic_string<char>, User*>::iterator’ 
     virtual iterator begin() const = 0; 
        ^
    ../HashTable/baseHashTable.h:27:8: note: because the following virtual functions are pure within ‘BaseHashTable<std::basic_string<char>, User*>::iterator’: 
     class iterator 

Является ли моя структура кода уместно? Как избавиться от ошибок компилятора: не может выделить объект абстрактного класса?

Code: 
// Instantiating the hash table 
myUserHashTable = new HashTable<string, User*>; 

     template<class KeyType, class ValueType> 
     class BaseHashTable // abstract class 
     { 
      class iterator 
     { 
     public: 

      virtual const ValueType& operator*() const = 0; 
      virtual iterator operator++() = 0; 

      bool operator==(const iterator& other) const 
      { 
       return (row == other.row && parent_ == other._parent); 
      } 

      bool operator!=(const iterator& other) const 
      { 
       return !(*this == other); 
      } 

      friend class BaseHashTable; 

      virtual BaseHashTable<KeyType,ValueType>* getParent() const = 0; 

      protected: 
       iterator(int row, const BaseHashTable* parent) 
       { 
        this->row = row; 
        parent_ = parent; 
       } 

       int row; 
       const BaseHashTable* parent_; 
     }; 

     virtual iterator begin() const = 0; 
     virtual iterator end() const = 0; 

protected: 
int _size; 

     }; 

     template<class KeyType, class ValueType> 
     class HashTable : public BaseHashTable<KeyType, ValueType> 
     { 
      class iterator: public BaseHashTable<KeyType, ValueType>::iterator 
     { 
     public: 
      const ValueType& operator*() const 
      { 
       return getParent()->hashTB[this->row]->at(col).second; 
      } 

      iterator operator++() 
      { 
       if (getParent()->hashTB[this->row]->size() > col+1) 
       { 
        col += 1; 
        return *this; 

       } else { 

        for (int i = this->row+1; i < this->parent_->_size; ++i) 
        { 
         if(getParent()->hashTB[i]->size() > 0) 
         { 
          this->row = i; 
          col = 0; 
          return *this; 
         } 
        } 

        this->row = getParent()->_size; 
        col = 0; 
        return *this; 
       } 
      } 

      bool operator==(const iterator& other) const 
      { 
       return (this->col == other.col) ? BaseHashTable<KeyType, ValueType>::iterator::operator==(other) : false; 
      } 

      bool operator!=(const iterator& other) const 
      { 
       return !(*this == other); 
      } 

      HashTable<KeyType,ValueType>* getParent() const 
      { 
       return ((HashTable<KeyType, ValueType>*)this->parent_); 
      } 

      friend class HashTable<KeyType, ValueType>; 

      private: 
       iterator(int row, int col, const BaseHashTable<KeyType, ValueType>* parent): BaseHashTable<KeyType, ValueType>::iterator(row, parent) 
       { 
        this->col = col; 
       } 

       int col; 
     }; 

     iterator begin() const 
     { 
      typename std::vector<std::pair<KeyType, ValueType> >::iterator it; 

      int j = 0; 
      for (int i = 0; i < this->_size; ++i) 
      { 
       if(hashTB[i]->size() > 0) 
        return iterator(j,0, this); 
       j++; 
      } 

     } 

     iterator end() const { 
      return iterator(this->_size, 0, this); 
     } 

    protected: 
    std::vector<std::pair<KeyType, ValueType> >** hashTB; 
     }; 

     template<class KeyType, class ValueType> 
     class DoubleHashingHashTable : public BaseHashTable<KeyType, ValueType> 
     { 
      class iterator {/*Implementation*/ } : public BaseHashTable<KeyType, ValueType>::iterator 
      iterator begin() const {/*Implementation*/} 
      iterator end() const {/*Implementation*/} 
     }; 
+0

Вы определяете функцию 'begin' и' end' member в дочерних классах, но ничего не возвращаете? –

+0

В чем вопрос? –

+0

Я реализовал функции, но не написал здесь реализацию. Показывать пример сложно, поскольку в моем проекте более 30 файлов. –

ответ

0
virtual iterator begin() const = 0; 

Итератор не может быть абстрактным классом, или даже полиморфный класс вообще. Передача или возврат по значению требует создания нового, полного объекта класса итератора. Любые свойства производного класса будут удалены с помощью операции «среза».

Возможно, вы захотите тип erasure, где не полиморфный объект приобретает полиморфное поведение, обладая чем-то полиморфным. Легкий способ сделать это включает кучу, хотя и, как правило, итераторы (итераторы контейнеров, во всяком случае) избегают сложности выделения кучи.

+0

Спасибо! Так что в принципе мне придется писать все классы итераторов без какого-либо наследования? –

+0

@SaurabhJain Частное наследование может быть удобным, особенно для использования сходства между «итератором» и «const_iterator». Однако, если есть особая причина, пользователь не должен видеть иерархию. – Potatoswatter

+0

Я вижу. спасибо –

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