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-
因为实例在循环中,内存被破坏。 但这只是一个例子,我必须实际使用循环。 我该怎么解决这个。。。?
。。。。。。。。。。。。 。。。。。。。。。。
您可以使用std::shared_pointer
或std::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)));
但是您必须记住删除堆上的对象,否则您将会出现内存泄漏