簡體   English   中英

C++ class 與模板成員變量。 和參數 memory 輸出

[英]C++ class with template member variable. and parameter memory out

struct PacketBase
{
    virtual ~PacketBase() {}

    template<class T> 
    const T& get() const
    {
        return static_cast<const PacketVal<T>&>(*this).val;
    }

    template<class T> 
    void set(const T& rhs)
    {
        return static_cast<PacketVal<T>>(*this).val = rhs;
    }
};


template <typename T>
struct PacketVal : public PacketBase
{
    T val;

    PacketVal(const T& rhs) : val(rhs) {}
    ~PacketVal() {}
};


class CResponsePacket
{
private:
    std::vector<std::pair<int, const PacketBase*>> m_vPacketData;

public:
    void addValue(int n, const PacketBase& packetData)
    {
        m_vPacketData.emplace_back(std::make_pair(n, &packetData));
    }

    void print()
    {
         for ( auto& data : m_vPacketData )
         {
              std::printf("%d - ", data.first);
              std::printf("%s\n", data.second->get<std::string>().c_str());
         }
    }
};

CResponsePacket 具有模板 class 成員變量。

int main()
{
    CResponsePacket packet;
    std::string strAAA("AAA");

    PacketVal<std::string> pVal(strAAA);
    packet.addValue(1, pVal);

    for ( int nIdx = 0; nIdx < 5; ++nIdx )
    {
        PacketVal<std::string> pp(strAAA);
        packet.addValue(nIdx + 1, pp);
    }

    packet.print();

    return 0;
}

結果是

1 - AAA
1 -
2 -
3 -
4 -
5 -

因為實例處於循環中,所以 memory 被銷毀。 但這只是一個例子,實際上我必須使用循環。 我該如何解決這個...?

…………………………………………………………………………………………………………………………………………

您可以使用std::shared_pointerstd::unique_ptr (取決於您的使用),因此矢量看起來像這樣:

std::vector<std::pair<int, std::shared_pointer<PacketBase>>> m_vPacketData;

那么addValue方法應該如下所示:

void addValue(int n, const PacketBase& packetData)
{
    m_vPacketData.emplace_back(
        std::make_pair(
             n, 
             std::make_shared<PacketBase>(packetData)
        )
    );
}

這將在堆上復制packetData ,並將引用存儲在共享指針中。 如果你不制作這個副本,那么你必須在PacketBase中定義一個新的構造函數

class PacketBase{
public: 
     PacketBase(PacketBase&& el): attr(std::move(el.attr))... {...}
}

然后重新定義接受右值引用的addValue

void addValue(int n, PacketBase&& packetData)
{
    m_vPacketData.emplace_back(
        std::make_pair(
             n, 
             std::make_shared<PacketBase>(std::move(packetData))
        )
    );
}

然后實際上從main調用正確的addValue

for ( int nIdx = 0; nIdx < 5; ++nIdx )
{
    PacketVal<std::string> pp(strAAA);
    packet.addValue(nIdx + 1, std::move(pp));
}

或者實際上只是:

for ( int nIdx = 0; nIdx < 5; ++nIdx )
    packet.addValue(nIdx + 1, PacketVal<std::string>(strAAA););

這顯然會迫使您重寫整個 class,因為您正在更改屬性類型...實現此目的的另一種方法是從

m_vPacketData.emplace_back(std::make_pair(n, &packetData));

m_vPacketData.emplace_back(std::make_pair(n, new PacketVal(packetData)));

但是你必須記住刪除堆上的對象,否則你將有 memory 泄漏

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM