首页 > 解决方案 > 如何正确使用具有抽象指针类型的模板类

问题描述

我创建了一个带有模板 Node 类的 List 来保存不同的数据类型,例如 Node<int>,但也包含更复杂的类型,例如 Node<BaseEvent*>。

我还有一个事件容器类来保存不同的事件对象,所以它有一个成员参数

List<BaseEvent*> events;

其中 BaseEvent 是具有非抽象派生类的抽象类。

在事件容器中,我有一个名为“add”(见下文)的方法,它向该事件添加一个新事件。

BaseEvent* eventClone = event.clone();

克隆返回一个指向新派生对象的指针,例如:

new OpenEvent(*this);

一旦它调用列表的插入方法,它就会实例化一个新节点(见下文),并在节点构造函数中分配值,如下所示:

value(new T(new_value)) 

所以基本上它分配了一个指针内存(T=BaseEvent*)。

我想我可能会丢失 eventClone 指针并且有内存泄漏。问题是,当我调试它时,我看到:(T* value;又名BaseEvent** value)和BaseEvent* eventClone内存中的地址相同。

我不确定当我delete value在 Node 的析构函数中这样做时,它是否只会释放指向 BaseEvent* 的指针分配或它所拥有的数据。

欢迎任何见解!


相关代码片段

节点<T>

    template <class T>
    class Node
    {
    public:

        Node(const T& new_value, Node* new_next = NULL, Node* new_prev = NULL);
        ~Node();

        const T& getValue() const;
        Node<T>* getNext() const;
        Node<T>* getPrev() const;
        void setNext(Node* node);
        void setPrev(Node* node);

    private:
        T* value;
        Node* next;
        Node* prev;
    };

    template <class T>
    Node<T>::Node(const T& new_value, Node* new_next, Node* new_prev) : 
        value(new T(new_value)) 
    {
        next = new_next;
        prev = new_prev;
    }

    template <class T>
    Node<T>::~Node()
    {
        delete value;
    }
    ...

使用 Node<T> 的链表

    template <class T>
    class List
    {
    public:
        List();
        ~List();
        
        int getSize() const;
        Node<T>* getFirst() const;
        Node<T>* getNext(Node<T>& node) const;
        Node<T>* getPrev(Node<T>& node) const;
        void insertStart(const T& data);
        void insertLast(const T& data);
        void insertAfter(Node<T>& target, const T& data);
        void insertBefore(Node<T>& target, const T& data);
        void removeNode(Node<T>& node);
        bool contains(const T data);


    private:
        Node<T>* head;
        int size;
    };

    template <class T>
    List<T>::List() : head(NULL), size(0)
    {
    }

    template <class T>
    List<T>::~List()
    {
        Node<T>* temp;
        while (head)
        {
            temp = head;
            head = head->getNext();
            delete temp;
            size--;
        }
    }
    ...
    template <class T>
    void List<T>::insertStart(const T& data) {
        if (size == 0)
        {
            head = new Node<T>(data);
        }
        else
        {
            Node<T>* temp = new Node<T>(data, head);
            head->setPrev(temp);
            head = temp;
        }

        size++;
    }
    ...

事件容器类:

    class EventContainer
    {
    public:
        EventContainer() :
            events(List<BaseEvent*>()) {}
        ~EventContainer() {}

        virtual void add(const BaseEvent&);
        
        class EventIterator
        {
        public:
            EventIterator() :
                current(NULL) {}
            EventIterator(Node<BaseEvent*>& node) :
                current(&node) {}
            EventIterator(Node<BaseEvent*>* node) :
                current(node) {}
            ~EventIterator() {}

            EventIterator& operator=(const EventIterator& nodeIterator) {
                current = nodeIterator.current;
                return *this;
            }
            EventIterator& operator++() {
                current = current->getNext();
                return *this;
            }
            BaseEvent& operator*() const {
                return *(current->getValue());
            }

            friend bool operator==(const EventIterator& iterator1, const EventIterator& iterator2) {
                return iterator1.current == iterator2.current;
            }

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

        private:
            Node<BaseEvent*>* current;
        };

        virtual EventIterator begin() const;
        virtual EventIterator end() const;

    private:
        List<BaseEvent*> events;
    };

方法的实现add

    void EventContainer::add(const BaseEvent& event) {
        BaseEvent* eventClone = event.clone();
        if (events.getSize() == 0)
        {
            events.insertStart(eventClone);
            return;
        }

        Node<BaseEvent*>* current = events.getFirst();
        while (current != NULL)
        {
            if (*eventClone < *(current->getValue()))
            {
                events.insertBefore(*current, eventClone);
                return;
            }
            current = current->getNext();
        }

        events.insertLast(eventClone);
    }

    EventContainer::EventIterator EventContainer::begin() const {
        return events.getFirst();
    }
    
    EventContainer::EventIterator EventContainer::end() const {
        return NULL;
    }

标签: c++c++11templatesinheritanceabstract-class

解决方案


推荐阅读