繁体   English   中英

C ++中的继承和虚拟析构函数问题

[英]Issue with inheritance and virtual destructors in C++

所以我有两个类,一个是抽象的,一个不是。

抽象类是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;
        }

您的基类应具有virtual析构函数,但不能具有 virtual析构函数(*)。

纯虚函数(即标记为virtual函数并在其签名后附加= 0后缀的函数)没有实现。 但是,基类的析构函数始终需要由子类的析构函数调用,并且您应该为其提供一个定义(可能为空):

template<class T>
class Iterator {

    public:
        //~Constructors/Destructors------------//
        /*
         * Destroys necessary resources.
         */
        virtual ~Iterator() { }
    ...

另请参阅有关StackOverflow的此问答以获取相关信息。

(*)如链接的问答中所述,可能有一个纯虚拟析构函数(仍需要定义),但我认为它不是特别好的编程习惯。

无论是否为纯基本析构函数,都需要提供一个定义。

virtual ~Iterator() { }

应该修复它。

PS:仅供参考,这里有一个std链接列表,std :: list

尽管你的析构函数是纯虚, 需要提供在基类中实现的类型是可用的。

只需为Iterator添加一个空的析构函数即可; 您无需丢失“纯”析构函数(尽管由于您已经拥有其他纯虚拟方法,这没有多大意义)。

其他人已经回答了如何解决您看到的错误,但是您的问题

在抽象Iterator基类中是否需要虚拟析构函数?

尚未回答。

答案取决于您(和其他用户)打算如何使用这些类。 没有virtual析构函数没什么错, 除非有人决定通过Iterator指针delete LinkedListIterator实例,否则一切都会正常工作。 例如:

Iterator<int> *iter = new LinkedListIterator<int>(...);
delete iter; // undefined behavior if Iterator destructor is not virtual

但是,由于您要实现迭代器类,因此有人动态分配实例的机会(更不用说尝试对其进行多态删除)的机会应该很小。 不过,既然你已经有了其他的虚拟功能,我想不出一个缺点来声明析构函数virtual无论是。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM