我有一个这样的课:

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/

10-13 06:18