提问者:小点点

带有模板成员变量的C++类。 和参数内存输出


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具有模板类成员变量。

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-

因为实例在循环中,内存被破坏。 但这只是一个例子,我必须实际使用循环。 我该怎么解决这个。。。?

。。。。。。。。。。。。 。。。。。。。。。。


共1个答案

匿名用户

您可以使用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))... {...}
}

然后重新定义接受rvalue引用的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););

这显然会迫使您重写整个类,因为您正在更改属性类型。。。 另一种可以实现这一点的方法是从

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

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

但是您必须记住删除堆上的对象,否则您将会出现内存泄漏

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(带有|模板|成员|变量|c++|类|参数|内存|输出)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?