这是我的代码:
void MIDITest::CreateNoteBlock() {
IMidiMsgExt* midiMessage = new IMidiMsgExt;
midiMessage->MakemidiMessageMsg(57, 100, 0, 0, 0);
queuedNotes.insert(*midiMessage);
midiMessage = new IMidiMsgExt;
midiMessage->MakemidiMessageMsg(60, 100, 0, tickSize * 38, 0);
queuedNotes.insert(*midiMessage);
midiMessage = new IMidiMsgExt;
midiMessage->MakemidiMessageMsg(62, 100, 0, 0, 0);
queuedNotes.insert(*midiMessage);
midiMessage = new IMidiMsgExt;
midiMessage->MakemidiMessageMsg(65, 100, 0, tickSize * 32, 0);
queuedNotes.insert(*midiMessage);
midiMessage = new IMidiMsgExt;
midiMessage->MakemidiMessageMsg(57, 0, tickSize * 111, 0);
queuedNotes.insert(*midiMessage);
midiMessage = new IMidiMsgExt;
midiMessage->MakemidiMessageMsg(60, 0, tickSize * 111, 0);
queuedNotes.insert(*midiMessage);
midiMessage = new IMidiMsgExt;
midiMessage->MakemidiMessageMsg(62, 0, tickSize * 75, 0);
queuedNotes.insert(*midiMessage);
midiMessage = new IMidiMsgExt;
midiMessage->MakemidiMessageMsg(65, 0, tickSize * 105, 0);
queuedNotes.insert(*midiMessage);
}
所以每个new
运算符都会分配一块内存。
我应该在queuedNotes中的任何free
之后使用insert
吗?或者它会在void
函数返回后释放? (即CreateNoteBlock的括号)。
或者,每次midiMessage
指针指向新的IMidiMsgExt
时,我都可以“重复使用”?
答案 0 :(得分:6)
答案是不要使用new
。创建具有自动存储持续时间的对象
IMidiMsgExt midiMessage;
然后您可以继续致电MakemidiMessageMsg
并将邮件的副本插入multiset
。
midiMessage.MakemidiMessageMsg(57, 100, 0, 0, 0);
queuedNotes.insert(midiMessage);
midiMessage.MakemidiMessageMsg(60, 100, 0, tickSize * 38, 0);
queuedNotes.insert(midiMessage);
//...
现在multiset
有一份所有消息的副本,并且在函数midiMessage
的末尾被销毁,并且不需要进行内存管理。
如果IMidiMsgExt
有一个类似于MakemidiMessageMsg
的构造函数,您可以在其中构建一个完整的消息,那么您可以进一步使用它,并使用类似
queuedNotes.insert(IMidiMsgExt(57, 100, 0, 0, 0));
queuedNotes.insert(IMidiMsgExt(60, 100, 0, tickSize * 38, 0));
现在我们甚至不需要midiMessage
。
答案 1 :(得分:5)
您是来自Java还是C#背景?在C ++中,您不必使用new
来创建对象,只需声明它们可以正常工作:
IMidiMsgExt midiMessage;
midiMessage.MakemidiMessageMsg(57, 100, 0, 0, 0);
queuedNotes.insert(midiMessage);
要么(这是我建议的解决方案),要么你必须明确释放对象:
IMidiMsgExt* midiMessage = new IMidiMsgExt;
midiMessage->MakemidiMessageMsg(57, 100, 0, 0, 0);
queuedNotes.insert(*midiMessage);
delete miniMessage;
答案 2 :(得分:1)
使用new动态分配IMidiMsgExt
似乎是多余的。你可以直接在堆栈上分配它(没有指针),然后当你的方法返回时它会被销毁。即:
void MIDITest::CreateNoteBlock() {
IMidiMsgExt midiMessage();
midiMessage.MakemidiMessageMsg(57, 100, 0, 0, 0);
queuedNotes.insert(midiMessage);
midiMessage = IMidiMsgExt();
midiMessage.MakemidiMessageMsg(60, 100, 0, tickSize * 38, 0);
queuedNotes.insert(midiMessage);
midiMessage = IMidiMsgExt();
midiMessage.MakemidiMessageMsg(62, 100, 0, 0, 0);
queuedNotes.insert(midiMessage);
midiMessage = IMidiMsgExt();
midiMessage.MakemidiMessageMsg(65, 100, 0, tickSize * 32, 0);
queuedNotes.insert(midiMessage);
midiMessage = IMidiMsgExt();
midiMessage.MakemidiMessageMsg(57, 0, tickSize * 111, 0);
queuedNotes.insert(midiMessage);
midiMessage = IMidiMsgExt();
midiMessage.MakemidiMessageMsg(60, 0, tickSize * 111, 0);
queuedNotes.insert(midiMessage);
midiMessage = IMidiMsgExt();
midiMessage.MakemidiMessageMsg(62, 0, tickSize * 75, 0);
queuedNotes.insert(midiMessage);
midiMessage = IMidiMsgExt();
midiMessage.MakemidiMessageMsg(65, 0, tickSize * 105, 0);
queuedNotes.insert(midiMessage);
}
答案 3 :(得分:1)
尝试使您的API更像C ++。
在堆栈中使用一个对象,而不是在堆中创建许多新对象。
void MIDITest::CreateNoteBlock() {
IMidiMsgExt midiMessage;
midiMessage.MakemidiMessageMsg(57, 100, 0, 0, 0);
queuedNotes.insert(midiMessage);
midiMessage.MakemidiMessageMsg(60, 100, 0, tickSize * 38, 0);
queuedNotes.insert(midiMessage);
// ...
}
在构造函数中初始化对象。为operator = (const IMidiMsgExt&)
定义IMidiMsgExt
。
void MIDITest::CreateNoteBlock() {
IMidiMsgExt midiMessage(57, 100, 0, 0, 0);
queuedNotes.insert(midiMessage);
midiMessage = IMidiMsgExt(60, 100, 0, tickSize * 38, 0);
queuedNotes.insert(midiMessage);
// ...
}
我想,insert()
期望const IMidiMsgExt&
。所以你可以直接传递刚刚初始化的对象:
void MIDITest::CreateNoteBlock() {
queuedNotes.insert({57, 100, 0, 0, 0});
queuedNotes.insert({60, 100, 0, tickSize * 38, 0});
// ...
}
顺便说一句:你应该更喜欢使用例如std::queue<>
queuedNotes
。然后,您将不会使用insert()
,而是使用push()
或emplace()
。 emplace()
的优点是,它构造容器中的对象而不是先创建它然后将其复制到容器中:
void MIDITest::CreateNoteBlock() {
queuedNotes.emplace(57, 100, 0, 0, 0);
queuedNotes.emplace(60, 100, 0, tickSize * 38, 0);
// ...
}
此外,您的typename IMidiMsgExt
向我发出信号,表示您正在尝试模仿C ++中的C#思维。这是可能的,但通常它不是首选的解决方案。从你的问题我不太了解你的类树和提供建议的基本要求,但在C ++中通常是代码味道。