在没有智能指针的情况下将指针返回到堆对象 [英] Returning pointers to heap objects without smart pointers

查看:102
本文介绍了在没有智能指针的情况下将指针返回到堆对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象类IPacket.

I have an abstract class, IPacket.

/*
 * Represents an abstract network packet.
 */
class IPacket
{

public:

    virtual void read(...) = 0;

    virtual void write(...) = 0;

    virtual int getID() const = 0;
};

我想(一直)返回一个类似的指针:

And I'd like to (and have been) returning a pointer to like so:

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();
};

现在显然,这是一种不好的做法;要求调用者删除一个指针,该指针甚至不是由它自己分配的.我相信,惯例是使用智能指针,即

Now obviously, this is bad practice; requiring the caller to delete a pointer that wasn't even allocated by itself. The convention I believe, is to use smart pointers, i.e.

class PacketMedium
{
public:

    std::unique_ptr<IPacket*> receivePacket();
};

但是,由于这是库代码,因此智能指针是一个nono,尽管事实上我宁愿避免使用它们.

But as this is library code, smart pointers are a nono, notwithstanding the fact I'd prefer to avoid them regardless.

我最好的选择是什么?

感谢您的帮助:)

之前已经有人问过这个问题,并且给出了很好的答案,尽管它们都建议使用智能指针,或者只是不在堆上分配.鉴于IPacket是抽象的,堆栈分配将无法工作.

this has been asked before and very good answers were given, although they all suggest smart pointers, or just not allocating on the heap. Given that IPacket is abstract, stack allocation wouldn't work.

推荐答案

一个想法是返回引用:

class PacketMedium {
public:
   IPacket &receivePacket();
private:
   IPacketImpl1 impl1;
   IPacketImpl2 impl2;
 };

receivePacket应该通过以下方式实现:

The receivePacket should be implemented in the following way:

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;
  }
}

请注意,使用参考文献时会有一些基本规则:

Note that there will be some ground rules when using the reference:

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

要解决这些问题,您可以对IPacket接口实施新功能:

To fix these problems, you could implement new function to IPacket interface:

virtual IPacket *clone() const=0;

这篇关于在没有智能指针的情况下将指针返回到堆对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆