C++:使用容器存放带有指针变量的类对象时的注意事项

注意事项:使用容器存放带有指针变量的类对象时一定要重载复制构造函数。下面示例说明:

定义两个类:
class DataItemRegValue
{
public:

    BYTE ModBusType;

    short DataMark;

    BYTE RegisterCnt;

public:

    DataItemRegValue();

    virtual ~DataItemRegValue();

};

class DataItem
{
public:

    BYTE ModBusType;

    BYTE DeviceNo;

    BYTE DataCnt;

    /// <summary>
    /// 数据项
    /// </summary>
    vector<DataItemRegValue>* m_pItemList;

public:

    DataItem(const BYTE& modbusType);

    DataItem(const DataItem& data);

    virtual ~DataItem();

public:

    int GetLength();

    int ReadBuffer(const int& pos, BYTE* pBuffer);
};

//DataItem
DataItem::DataItem(const BYTE& modbusType)
{
    ModBusType = modbusType; 

    ModBusType = 0;

    DeviceNo = 0;

    DataCnt = 0;

    //堆上分配内存。
    m_pItemList = new vector<DataItemRegValue>();
}

//复制构造函数,加入容器时,或通过复制创建一个新的对象时调用它。
DataItem::DataItem(const DataItem& data)
{
    this->DataCnt = data.DataCnt;
    this->DeviceNo = data.DeviceNo;
    this->ModBusType = data.ModBusType;
    this->m_pItemList = new vector<DataItemRegValue>();
    this->m_pItemList->assign(data.m_pItemList->begin(),data.m_pItemList->end());

}

//析构函数,释放内存。
DataItem::~DataItem()
{
    if(m_pItemList != nullptr)
    {
        m_pItemList->clear();
        delete m_pItemList;
        m_pItemList = nullptr;
    }
}


//调用
其中m_pItemList定义为vector容器:
vector<DataItem>* m_pItemList = new vector<DataItem>();

int ReadBuffer(const int& pos, BYTE* pBuffer,const int& nBufferSize)
{
    if (pos < 0 || pBuffer == nullptr)
    {
        return -1;
    }

    CUnPacket unpk(pos, pBuffer);

    int CurIndex = unpk.GetCurIndex();

    for (; CurIndex < nBufferSize; )
    {
        DataItem item(ModBusType);
        item.ReadBuffer(CurIndex, pBuffer);
        CurIndex += item.GetLength();
        
/*m_pItemList是一个容器,注意了,在数据被push_back到容器中时,会调用DataItem的复制构造函数。如果没有重载DataItem的复制构造函数,则系统会调用默认的复制构造函数,这样,同一个指针值存放在两个不同的指针变量中,DataItem变量构造了两次,声明局部变量时调用构造函数创建对象,在数据push_back到容器中时调用了复制构造函数创建了另一个对象放入容器m_pItemList中,当这两个对象调用析构函数销毁时,同一个指针值指向同一块内存,被析构了两次,从而导致异常报误。*/

        m_pItemList->push_back(item);
    }
    return 0;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值