所以我有两个类,一个是抽象的,一个不是。
抽象类是Iterator,具体的是LinkedListIterator。两者的代码都在帖子的底部。
我遇到的问题是下面的代码,我在LinkedListIterator中遇到1个错误 在析构函数的最后一行说
undefined reference to `Iterator<int>::~Iterator()'
现在我尝试注释掉虚拟~Iterator()析构函数,没有错误,但我收到警告说:
Class '[C@800c1' has virtual method 'remove' but non-virtual destructor
所以我的问题是:我是否需要在抽象Iterator基类中使用虚拟析构函数?我已经读过你应该总是有一个,但在这种情况下,LinkedListIterator中的析构函数只是设置值,它不会释放任何东西......
谢谢!
迭代器代码:
template<class T>
class Iterator {
public:
//~Constructors/Destructors------------//
/*
* Destroys necessary resources.
*/
virtual ~Iterator() = 0;
//~Methods-------------------//
/*
* Informs the user whether there are more elements to be iterated
* over in a List.
*
* @return true if there are more elements to iterate over, false otherwise.
*/
virtual bool hasNext() = 0;
/*
* Gets the next element to iterate over.
*
* @return the next element in the iteration.
*/
virtual T next() = 0;
/*
* Adds an element to the List being iterated over.
*
* @param element the element to add.
* @return true if successful, false otherwise.
*/
virtual bool add(T element) = 0;
/*
* Removes the element last returned by next from
* the List being iterated over.
*
* @return true if successful, false otherwise.
*/
virtual bool remove() = 0;
};
相关的LinkedListIterator代码(这是一个很长的类):
template<class T>
class LinkedListIterator : public Iterator<T> {
private:
//~Data Fields---------------------------------//
/*
* Pointer to the node that the iterator is currently at.
*/
Node<T>* current;
/*
* Pointer to the LinkedList being iterated through.
*/
LinkedList<T>* list;
/*
* Boolean value indicating whether next has been called since
* the last remove operation.
*/
bool nextCalled;
public:
//~Constructors/Destructors------------------//
/*
* Constructor for LinkedListIterator, takes in a pointer to a Node
* to initialize current to point to (intended to be the head of the
* the LinkedList).
*
* @param theList pointer to the LinkedList being iterated through.
*/
LinkedListIterator(LinkedList<T>* theList) {
current = theList->head;
list = theList;
nextCalled = false;
}
/*
* Destructor, resets pointer values to 0.
*/
~LinkedListIterator() {
current = 0;
list = 0;
}
答案 0 :(得分:6)
您的基类应该有virtual
析构函数,但不能是纯 virtual
析构函数(*)。
纯虚函数(即标记为virtual
并且其签名后附有= 0
后缀的函数)没有实现。但是,基类的析构函数总是需要由子类的析构函数调用,你应该为它提供一个定义(可能是一个空的):
template<class T>
class Iterator {
public:
//~Constructors/Destructors------------//
/*
* Destroys necessary resources.
*/
virtual ~Iterator() { }
...
另请参阅 this Q&A on StackOverflow 了解相关信息。
(*)正如链接Q&amp; A中所提到的,可能有一个纯虚拟析构函数(仍然需要定义),但我认为它不是一个特别好的编程实践。
答案 1 :(得分:3)
您需要为虚拟基础析构函数提供定义,无论它是否纯粹。
virtual ~Iterator() { }
应该修复它。
PS:纯粹是FYI,有一个std链接列表,std :: list
答案 2 :(得分:3)
尽管你的析构函数是纯虚构的,但你做需要在基类中提供一个可用的类型的实现。
只需为Iterator
添加一个空的析构函数;你不需要失去“纯粹的”析构函数(虽然它已经有了其他纯虚方法,因此没有多大意义)。
答案 3 :(得分:2)
其他人已经回答了如何解决您所看到的错误,但问题是
我是否需要在抽象Iterator基类中使用虚拟析构函数?
尚未得到答复。
答案取决于您(和其他用户)打算如何使用这些类。没有virtual
析构函数并且一切都能正常工作直到有人通过delete
指针决定LinkedListIterator
Iterator
个实例。例如:
Iterator<int> *iter = new LinkedListIterator<int>(...);
delete iter; // undefined behavior if Iterator destructor is not virtual
但是,由于您正在实现迭代器类,因此有人动态分配实例的可能性(更不用说尝试对其进行多态删除)应该是最小的。但是,既然你已经有了其他虚函数,我也不会想到声明析构函数virtual
的缺点。