转换迭代器指向的对象

时间:2016-04-21 09:48:36

标签: c++ inheritance casting iterator

我有这个多集合容器:

multiset<IMidiMsgExt, IMidiMsgExtComp> queuedNotes;

IMidiMsgExt是我自己创建的一个结构(我需要一个额外的属性,mTick)扩展IMidiMsg

struct IMidiMsgExt : public IMidiMsg
{
    IMidiMsgExt() {
    }

    double mTick = 0.;

    void IMidiMsgExt::MakeNoteOnMsg(int noteNumber, int velocity, int offset, double tick, int channel)
    {
        Clear();
        mStatus = channel | (kNoteOn << 4);
        mData1 = noteNumber;
        mData2 = velocity;
        mOffset = offset;
        mTick = tick;
    }

    void IMidiMsgExt::MakeNoteOffMsg(int noteNumber, int offset, double tick, int channel)
    {
        Clear();
        mStatus = channel | (kNoteOff << 4);
        mData1 = noteNumber;
        mOffset = offset;
        mTick = tick;
    }

    void IMidiMsgExt::Clear()
    {
        mOffset = 0;
        mStatus = mData1 = mData2 = 0;
        mTick = 0.;
    }
};

下一步:我在queuedNotes多个集合中存储了一些IMidiMsgExt个对象,其中包含:

IMidiMsgExt* noteOff = new IMidiMsgExt;
noteOff->MakeNoteOffMsg(57, 0, tickSize * 111, 0);
queuedNotes.insert(*noteOff);

现在,我需要使用名为SendMidiMsg(IMidiMsg* pMsg)的函数(以IMidiMsg类型作为输入)将对象IMidiMsgExt发送给它。

我将列表中的第一个对象提取到迭代器:

auto midiMessage = queuedNotes.begin();

但是当我尝试施放它并使用SendMidiMsg时:

SendMidiMsg((IMidiMsgExt*)midiMessage);

它说no suitable conversion function from "std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<IMidiMsgExt>>>" to "IMidiMsg *" exists

我哪里错了?我应该使用dynamic casting吗?

1 个答案:

答案 0 :(得分:4)

auto midiMessage = queuedNotes.begin();

midiMessage的类型为std::multiset::iterator。并且它无法转换为您的类型IMidiMsgExt。 Iterator是一个与指针行为类似的对象,因此您可以使用解除引用运算符(*)来获取它指向&#34;的对象。您也不需要将派生对象强制转换为其基础,这是隐式完成的。您需要做的就是获取迭代器指向&#34;指向的地址。获取指向IMidiMsgExt的指针:

SendMidiMsg(&*midiMessage);

快速分解&*midiMessage

  variable    -     type
midiMessage   - std::multiset::iterator
*midiMessage  - IMidiMsgExt
&*midiMessage - IMidiMsgExt*

修改 关于你的const_iterator错误。 std::multiset::begin() is supposed to always return const_iterator。你的函数SendMidiMsg()想要一个非常量指针 - 它说它想要编辑消息。 multiset不允许更改元素。

您可以复制邮件,然后拨打SendMidiMsg()。如果您不再需要容器内的消息,您也可以在之后将其删除。

auto msg = *midiMessage;
SendMidiMsg(&msg);
queuedNotes.erase(midiMessage);

注意:好像你的程序中有内存泄漏。您使用new创建消息,但我没有看到任何要删除的调用,以释放内存。

IMidiMsgExt* noteOff = new IMidiMsgExt;
noteOff->MakeNoteOffMsg(57, 0, tickSize * 111, 0);
queuedNotes.insert(*noteOff);