我有一个抽象类,IPacket。
/*
* Represents an abstract network packet.
*/
class IPacket
{
public:
virtual void read(...) = 0;
virtual void write(...) = 0;
virtual int getID() const = 0;
};
我想(并且已经)返回一个指向这样的指针:
class PacketMedium
{
/*!
* Returns a pointer to the next pending packet or NULL if there are no packets pending.
* \note The object must deleted when you are finished with it.
*/
IPacket* receivePacket();
};
很明显,这是不好的做法;要求调用者删除一个甚至没有被自己分配的指针。我认为的惯例是使用智能指针,即
class PacketMedium
{
public:
std::unique_ptr<IPacket*> receivePacket();
};
但由于这是库代码,所以智能指针是一个 nono,尽管我宁愿无论如何都避免使用它们。
我最好的选择是什么?
感谢您的帮助:)
编辑:之前有人问过这个问题并且给出了很好的答案,尽管他们都建议使用智能指针,或者只是不在堆上分配。鉴于 IPacket
是抽象的,堆栈分配将不起作用。
最佳答案
一个想法是返回一个引用:
class PacketMedium {
public:
IPacket &receivePacket();
private:
IPacketImpl1 impl1;
IPacketImpl2 impl2;
};
receivePacket 的实现方式如下:
IPacket &receivePacket() {
int data = receiveint();
if (data==0) { // impl1
float data = receivefloat();
impl1.data = data;
return impl1;
} else { // impl2
std::string data = receivestr();
impl2.str = data;
return impl2;
}
}
请注意,在使用引用时会有一些基本规则:
- 两次调用 receivePacket() 是危险的。第二次调用它可能会删除现有数据。
- 您收到的数据应立即使用。长时间存储 IPackets 是危险的。
要解决这些问题,您可以为 IPacket 接口(interface)实现新功能:
virtual IPacket *clone() const=0;
关于c++ - 在没有智能指针的情况下返回指向堆对象的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17501556/