我有一个这样的课:
class cSerialMessage
{
public:
cSerialMessage(const enumMessages type, std::string txmessage = "") {rxAnswer="";};
// Get/Set Methods
// ...
bool AddIntParam(); // Stores an int as parameter for the message
void BuildCompleteMessage() // Build the whole message following the protocol rules
private:
enumMessages m_type;
std::string m_txmessage, m_rxanswer;
// [...]
};
然后我有另一个类“管理”消息队列:
class cMsgManager
{
public:
cMsgManager();
// [...]
cSerialMessage* NewMessage(eMessages MSG);
bool AddParameter(int Param);
bool QueueMessage(bool FirstPosition);
private:
deque<cSerialMessage> cMS;
cSerialMessage* tempMsg;
}
相关部分是创建cSerialMessage并将其添加到双端队列的地方。
cSerialMessage* cMsgManager::NewMessage (eMessages MSG)
{
// Begin the creation of a new message
if (tempMsg!=nullptr) {
// there was already a temporary message
OutputDebugString ("NOPE!");
return nullptr;
}
tempMsg = new cSerialMessage(MSG);
return tempMsg;
}
//------------------------------------------------------------------------------
bool cMsgManager::AddParameter (int Param)
{
if (tempMsg==nullptr) {
// this means that NewMessage() was'nt called before.
OutputDebugString ("NOPE!);
return false;
}
return tempMsg->AddIntParam(Param);
}
//------------------------------------------------------------------------------
bool cMsgManager::QueueMessage(bool FirstPosition)
{
if (tempMsg==nullptr) {
// this means that NewMessage() was'nt called before.
OutputDebugString ("NOPE!);
return false;
}
// Build the final message
tempMsg->BuildCompleteMessage();
if (FirstPosition) {
cMS.push_front(*tempMsg);
}else{
cMS.push_back(*tempMsg);
}
delete tempMsg;
tempMsg=nullptr;
return true;
}
尽管有关于此主题(this is very detailed)的所有问题,但我仍然感到困惑。
我应该删除我的tempMsg吗?它是复制到双端队列中,还是最后由tempMsg指向的数据是稍后将从双端队列中访问的数据?
还是我要创建复制构造函数和复制分配运算符?
最佳答案
我应该删除我的tempMsg吗?
是的,按照书面规定,您必须delete
您的tempMsg
,或在程序生命周期内重用单个实例(在第一个实例之后不能再创建new
)。重用它可能需要在每次重用之前清除它,这似乎不值得。
它是复制到双端队列中,还是最后由tempMsg指向的数据是稍后将从双端队列中访问的数据?
它被复制; push_back
接收引用,但仅记录用于复制或移动(由于您传递了一个l值,因此它将被复制)。您可以通过执行cMS.push_front(std::move(*tempMsg));
节省一些工作,以清空tempMsg
(因为您之后将要删除它,因此也可以保存副本)。
还是我要创建复制构造函数和复制分配运算符?
假设cSerialMessage
的所有成员本身都是可正确复制的(没有原始指针等),并且您尚未定义任何自定义复制/移动操作或析构函数,则应该没问题;编译器生成的副本构造函数将正常工作。另一方面,cMsgManager
需要完整的3/5构造函数和析构函数规则,因为您没有为tempMsg
使用智能指针或值语义。
注意整个动态分配是毫无意义的/浪费的。您可以将tempMsg
设置为cSerialMessage
(而不是cSerialMessage*
),然后按值使用它。您可以将其保留为实例的属性,或者只是让NewMessage
返回实际的新消息,而根本不将副本存储在本地。本地副本将使线程化或可重入代码成为噩梦,因此按值返回新消息并由调用方管理可能是一个更好的主意。
关于c++ - 被类 vector 混淆:“三巨头”,在push_back之后删除类和资源管理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53558935/