c++ - 在没有智能指针的情况下返回指向堆对象的指针

标签 c++ pointers memory

我有一个抽象类,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;
  }
}

请注意,在使用引用时会有一些基本规则:

  1. 两次调用 receivePacket() 是危险的。第二次调用它可能会删除现有数据。
  2. 您收到的数据应立即使用。长时间存储 IPackets 是危险的。

要解决这些问题,您可以为 IPacket 接口(interface)实现新功能:

virtual IPacket *clone() const=0;

关于c++ - 在没有智能指针的情况下返回指向堆对象的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17501556/

相关文章:

c++ - MFC 应用程序静默关闭

c++ - 文件到数组再到结构

c++ - 为模板化容器类专门化成员函数

c - 在 C 中使用指针结构

powershell - 使用Powershell Windows 2008导出特定进程

c++ - 将位数据输出到二进制文件C++

c - 与 IEEE-754 相比,内存中的浮点位模式按位反转了吗?

c - 切换引用和偏移时奇怪的数组逻辑

caching - Cache、Store Buffer 和 BIU/WCB 在 CPU 中是各自有单独的物理缓冲区,还是只有一个?

c - 函数中分配的内存会发生什么情况?