C++ 多态性和原始指针的使用

jka*_*ang 1 c++ polymorphism raw-pointer

我正在编写一个数据包处理器并具有以下类:

class Parser {
  private:
    Packet* curr_pkt;
  public:
    void parsePacket(unsigned char byte) {
      if(byte == SyncPacket::headerVal) {
        SyncPacket pkt;
        curr_pkt = &pkt;
      }
      if(byte == SyncPacket::headerVal) {
        TypeAPacket pkt;
        curr_pkt = &pkt;
      }
    }
};
class Packet {
  public:
    void parseByte(unsigned char byte) {}
};
class SyncPacket : public Packet {
  public:
    static const unsigned char headerVal = 0x0A;
    void parseByte(unsigned char byte) {
      <do sync>
    }
};
class TypeAPacket : public Packet {
  public:
    static const unsigned char headerVal = 0x0B;
    void parseByte(unsigned char byte) {
      <do type A decode>
    }
};

int main() {
  std::vector<unsigned char> chars;
  <stream in characters>

  Parser pktParser;
  for(unsigned char byte: bytes) {
    pktParser.parseByte(byte);
  }
}
Run Code Online (Sandbox Code Playgroud)

这似乎工作得很好,实际上我认为这就是多态性的用途。但我的问题是:我应该担心这里使用的原始指针吗?是否有更推荐的方法通过智能指针来做到这一点?

例如,在这一行中:

      if(byte == SyncPacket::headerVal) {
        SyncPacket pkt;
        curr_pkt = &pkt;
      }
Run Code Online (Sandbox Code Playgroud)

从技术上讲,pkt 在if语句之后超出了范围,因此通常它的生命周期就会结束。但因为 curr_pkt 指向它,所以它继续存在。这是一个潜在的问题,不是吗?

小智 5

从技术上讲,pkt 在 if 语句之后超出了范围,因此通常它的生命周期就会结束。

这是正确的,但技术上没有任何内容。

但因为 curr_pkt 指向它,所以它继续存在。

但这是不正确的,该对象此时不再存在,指针被视为悬空,任何取消引用它的尝试都将是未定义的行为。

如果你成功地完成了这项工作,那么你就是幸运的。

是否有更推荐的方法通过智能指针来做到这一点?

与其说是一种“更推荐”的方式,不如说是一种真正有效的方式,是的。

您确实可以使用智能指针来完成代码想要表达的内容。(您不需要智能指针即可到达那里,但它确实使它更安全)。

class Parser {
  private:
    std::unique_ptr<Packet> curr_pkt;
  public:
    void parsePacket(unsigned char byte) {
      if(byte == SyncPacket::headerVal) {
        curr_pkt = std::make_unique<SyncPacket>();
      }
      if(byte == SyncPacket::headerVal) {
        curr_pkt = std::make_unique<TypeAPacket>();
      }
    }
};
Run Code Online (Sandbox Code Playgroud)