改变班级的更好方法?

时间:2017-04-11 08:29:43

标签: c++

我有一个程序从文件中读取一些字节。如果第二个字节恰好为0,则应将当前类型转换为正确的类型。

这就是我所拥有的:

struct Event {
    virtual ~Event() {}
};

struct MidiEvent : public Event {
    unsigned m_channel;
    uint8_t byte1;
    uint8_t byte2;
    MidiEvent(uint8_t channel) : m_channel{ channel } {}
};

struct EventNoteOff : public MidiEvent {
    uint8_t note() { return byte1; }
    uint8_t velocity() { return byte2; }
    EventNoteOff(std::fstream& t_midi_file, uint8_t channel);
};

struct EventNoteOn : public MidiEvent {
    uint8_t note() { return byte1; }
    uint8_t velocity() { return byte2; }
    EventNoteOn(std::fstream& t_midi_file, uint8_t channel);
};

这是程序决定哪个类分配给每个字节的部分:

// track_type and track_chanel is a "uint8_t", m_event is a "Event *" and t_midi_file is a std::fstream opened with 'in' and 'binary' flags.

switch (track_type) {
    case 0x80:
        m_event = new EventNoteOff{ t_midi_file, track_channel };
        break;
    case 0x90:
        t_midi_file.seekg(1, t_midi_file.cur);
        char c;
        t_midi_file.read(&c, 1);
        t_midi_file.seekg(-2, t_midi_file.cur);
        if (c == 0)
            m_event = new EventNoteOff{ t_midi_file, track_channel };
        else
            m_event = new EventNoteOn{ t_midi_file, track_channel };
        break;
    ...
}

每当track_type为0x90且byte2的值为0时,我希望m_event的行为类似EventNoteOff*,其值与之前相同,而不是EventNoteOn* 1}}。我的尝试有效,但我觉得这种方法很脏,因为它涉及移动文件读取指针并创建时间变量,当我认为它可以用reinterpret_cast完成。

我试过

    case 0x90:
        m_event = new EventNoteOn{ t_midi_file, track_channel };
        if(dynamic_cast<EventNoteOn*>(m_event)->velocity() == 0)
            m_event = reinterpret_cast<EventNoteOff*>(m_event);
        break;

没有运气。

有什么更好的方法可以做到这一点?

0 个答案:

没有答案