0

構造体 a または構造体 b のいずれかを保持するはずの両端キューがあります。問題は、構造の 1 つに、削除する必要があるポインターが含まれていることです。

#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ます。なぜ機能しないのかは理解していますが、問題は、ほとんど同じように見える2つの異なるクラスを作成せずにこれを機能させる方法があるかどうかです。

もちろん、これはクラスのほんの一部ですが、私の問題を説明する必要があります。

このような問題を抱えたのは私が初めてではないと思いますが、テンプレートの操作にあまり慣れていないため、何を探すべきかわかりませんでした。

4

3 に答える 3

1

これは機能するはずです m_PacketList.~deque();、デストラクタでは悪い考えです。とにかくキューのデストラクタが呼び出されるため、2 回呼び出すことになります。

于 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() への特定の呼び出しは必要ありません。実際には、コンパイラーがとにかく呼び出されることを保証するため、プログラムを壊すだけです (つまり、2 回呼び出すだけです)。

また、m_packet が存在しないためにコンパイラ エラーが発生する理由は、T == packet または T == packetUpdate に関係なく if-block がコンパイルされ、packetUpdate には m_packet がないためです。

于 2012-09-30T13:28:42.707 に答える