2015-05-03 154 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'成員函數,但它們不返回任何東西? –

+0

你的問題是什麼? –

+0

我已經實現了這些功能,但沒有在這裏寫實現。顯示一個例子是有點困難,因爲我的項目有超過30個文件。 –

回答

0
virtual iterator begin() const = 0; 

的迭代器不能是一個抽象類,或甚至一個多態類的。按值傳遞或返回需要創建一個新的迭代器類的完整對象。 「切片」操作將剝離派生類的任何屬性。

您可能需要類型擦除,其中非多態對象通過擁有多態屬性來獲取多態行爲。儘管這樣做的簡單方法涉及堆,但通常迭代器(無論如何,都是容器迭代器)避免了堆分配的複雜性。

+0

謝謝!所以基本上我將不得不編寫所有的迭代器類沒有任何繼承? –

+0

@SaurabhJain私有繼承可以很方便,特別是利用'iterator'和'const_iterator'之間的相似性。除非有特殊原因,否則用戶不應該看到層次結構。 – Potatoswatter

+0

我明白了。非常感謝 –