0

我有一个双端队列,它应该包含结构 a 或结构 b。问题是其中一个结构包含一个我必须删除的指针。

#pragma once

#include <iostream>
#include <deque>
#include <typeinfo>

struct packetUpdate {
    int recv;
    int packetID;
};

struct packet {
    int recv;
    int packetSize;
    char* m_packet;
};

template <class T>
class PacketQueue
{
private:
    int m_lastElement;
    int m_maxElementReached;
    int m_maxElements;

    std::deque<T> m_PacketList;

public:
    PacketQueue() { m_lastElement = -1; m_maxElements = 0; m_maxElementReached = 0; }
    ~PacketQueue() 
    { 
        if(typeid(T).name() == typeid(packet).name()) {
            for(int i = 0; i < m_lastElement+1; i++) {
                delete[] m_PacketList[i].m_packet;
            }
        }

        m_PacketList.~deque(); 
    }
};

这行不通。编译器告诉我packetUpdate没有 member m_packet。我理解为什么它不起作用,但问题是,有没有办法在不编写两个看起来几乎相同的不同类的情况下完成这项工作。

这当然只是班级的一小部分,但它应该能说明我的问题。

我想我不是第一个遇到这样问题的人,但由于我不习惯使用模板,所以我不知道我应该寻找什么。

4

3 回答 3

1

这应该可行,但是 m_PacketList.~deque();在析构函数中是一个坏主意,无论如何都会调用队列的析构函数,因此您要调用它两次。

于 2012-09-30T13:28:48.123 回答
0

您可以为类型数据包指定类析构函数,如下所示:

template<>
PacketQueue<packet>::~PacketQueue()
{
  //your code
}
于 2012-09-30T13:23:50.177 回答
0

最简单的方法就是在数据包中添加析构函数。如果这不可能,您可以添加策略模板来解决您的问题:

struct null_cleaner
{
    template <typename T>
    void perform_clean(T& v)
    { /* do nothing */ }
};

template <typename PacketQueue, typename Cleaner = null_cleaner>
class PacketQueue
{
    ~PacketQueue ()
    {
        for (int i = 0; i < m_PacketList.size(); ++i) {
            Cleaner::perform_clean(m_PacketList[i]);
        }  
    }
};

然后,当您添加需要清洁的类型时,您需要使用不同的清洁器:

// no cleaning
PacketQueue<packetUpdate> q1;

// requires cleaning
struct packet_cleaner
{
   void perform_clean(packet& p)
   {
       delete[] m_packet;
   }
};

// performs cleaning
PacketQueue<packet, packet_cleaner> q2;

此外,不需要对 m_PacketList.~deque() 进行特定调用,实际上它只会破坏您的程序,因为编译器会确保无论如何都会调用它(因此您只需调用它两次)。

另外,由于 m_packet 不存在而导致编译器错误的原因是,无论 T == packet 还是 T == packetUpdate 都会编译 if 块,并且对于 packetUpdate,没有 m_packet。

于 2012-09-30T13:28:42.707 回答