My code structure is as follows. I have a base abstract class which also has a nested abstract iterator. I inherit from the base class and i also inherit from the abstract base inherited class. To allocate the objects I use polymorphism:
我的代码结构如下。我有一个基本抽象类,它也有一个嵌套的抽象迭代器。我继承自基类,我也继承自抽象基继承类。要分配对象,我使用多态:
i am getting errors like:
我收到的错误如下:
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
Is my code structure appropriate? How to get rid of compiler errors : cannot allocate an object of abstract class?
我的代码结构合适吗?如何摆脱编译错误:无法分配抽象类的对象?
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*/}
};
1 个解决方案
#1
virtual iterator begin() const = 0;
An iterator cannot be an abstract class, or even a polymorphic class at all. Passing or returning by value requires creating a new, complete object of the iterator class. Any properties of a derived class will be stripped out by the "slice" operation.
迭代器不能是抽象类,甚至根本不是多态类。按值传递或返回需要创建迭代器类的新的完整对象。派生类的任何属性都将被“切片”操作剥离。
You might want type erasure, where a non-polymorphic object acquires polymorphic behavior by owning something polymorphic. The easy way of doing this involves the heap, though, and usually iterators (container iterators, anyway) avoid the complexity of heap allocation.
您可能需要类型擦除,其中非多态对象通过拥有多态的东西来获取多态行为。但是,执行此操作的简单方法涉及堆,并且通常迭代器(容器迭代器)无论如何都要避免堆分配的复杂性。
#1
virtual iterator begin() const = 0;
An iterator cannot be an abstract class, or even a polymorphic class at all. Passing or returning by value requires creating a new, complete object of the iterator class. Any properties of a derived class will be stripped out by the "slice" operation.
迭代器不能是抽象类,甚至根本不是多态类。按值传递或返回需要创建迭代器类的新的完整对象。派生类的任何属性都将被“切片”操作剥离。
You might want type erasure, where a non-polymorphic object acquires polymorphic behavior by owning something polymorphic. The easy way of doing this involves the heap, though, and usually iterators (container iterators, anyway) avoid the complexity of heap allocation.
您可能需要类型擦除,其中非多态对象通过拥有多态的东西来获取多态行为。但是,执行此操作的简单方法涉及堆,并且通常迭代器(容器迭代器)无论如何都要避免堆分配的复杂性。