将成员升级为单一属性类别的有效性

问题描述 投票:0回答:1

我可以用这样的方式定义一个具有单个成员的类,以便我始终可以将指向该成员的指针向上转换为该类的实例吗?

例如,给定这个类:

#include <cstdint>

class Packet {
public:
    static constexpr std::size_t k_size = 188;

    // Various functions omitted, they are all variations of this pattern
    bool is_flag(void) const {
        return (m_buffer[3] & 0x2) == 0x2;
    }

private:
    std::uint8_t m_buffer[k_size];
};

我如何支持以下内容

void some_func(std::uint8_t * buffer) {
    // Length checks, non-null checks omitted
    Packet * pkt = static_cast<Packet *>(buffer);
    if (pkt->is_flag()) {
        // ...
    }
}

编译器会让我用

(Packet *)buffer
代替
static_cast
——这格式正确吗?在某些情况下这会导致意外行为吗?有什么办法可以得到
static_cast
吗?

避免 X->Y 问题

我的目标是能够以两种方式使用这个类。在我生成数据包流的情况下,我想要拥有拥有其数据的

Packet
实例。它们存在于堆栈中,当我离开该函数时它们就会超出范围。单独地,用户可以提供指向包含多个数据包的缓冲区的指针。我希望能够对这些数据包执行操作,而不复制它们。

c++ casting
1个回答
0
投票

不知道为什么你希望课程像你想要的那样。这样的铸造就像用剪刀杂耍。以某种方式做对是可能的(我认为),但出错的方法太多了。安全的替代方案很简单:不要让

Paket
拥有数据。无论如何,数据似乎由其他人拥有,而您只有一个指向其他代码管理的数组的指针。

#include <cstdint>

class Packet {
public:
    static constexpr std::size_t k_size = 188;
    Packet(std::uint8_t* buffer) : m_buffer(buffer) {}
     
    // Various functions omitted, they are all variations of this pattern
    bool is_flag(void) const {
        return (m_buffer[3] & 0x2) == 0x2;
    }

private:
    std::uint8_t* m_buffer;
};

然后:

void some_func(std::uint8_t * buffer) {
    // Length checks, non-null checks omitted
    Packet pkt(buffer);
    if (pkt->is_flag()) {
        // ...
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.