繁体   English   中英

投射由迭代器指向的对象

[英]Cast an object that is pointed by an iterator

我有这个多集容器:

multiset<IMidiMsgExt, IMidiMsgExtComp> queuedNotes;

IMidiMsgExt是我创建的结构(扩展IMidiMsg ,我需要一个附加属性mTick ):

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

下一步:我将一些IMidiMsgExt对象存储在该queuedNotesIMidiMsgExt ,其内容如下:

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吗?

auto midiMessage = queuedNotes.begin();

midiMessage类型为std::multiset::iterator 而且它不能转换为您的IMidiMsgExt类型。 迭代器是一个行为类似于指针的对象,因此您可以使用取消引用运算符( * )获取其“指向”的对象。 您也不需要将派生对象强制转换为其基础,这是隐式完成的。 您需要做的就是获取迭代器“指向”的地址,以获取指向IMidiMsgExt的指针:

SendMidiMsg(&*midiMessage);

&*midiMessage快速分解:

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

编辑:关于您的const_iterator错误。 std :: multiset :: begin()应该总是返回const_iterator 您的函数SendMidiMsg()一个非const指针-表示要编辑消息。 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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM