【问题标题】:Avoid multiple copying in vector in C++在 C++ 中避免向量中的多次复制
【发布时间】:2013-03-08 06:10:32
【问题描述】:

我的问题是在下面给出避免向量复制中的多个副本。

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

class DataValue {
public:

    DataValue() { std::cout << "DataValue constructor called" << std::endl; }
    DataValue(DataValue const& other) { cout << "DataValue copy constructor called" << std::endl; }
    ~DataValue() { std::cout << "DataValue destructor is called" << std::endl; }
private:

};

class ItemDataHistory {
public:
    ItemDataHistory() { std::cout << "ItemDataHistory constructor called" << std::endl; }
    // ItemDataHistory(ItemDataHistory const & other) { std::cout << "ItemDataHistory copy constructor called" << std::endl; }
    ~ItemDataHistory() { std::cout << "ItemDataHistory destructor called" << std::endl; }
    std::vector<DataValue>& GetVecDataValues() { return m_vecDataValues; }  

private:
    std::vector<DataValue> m_vecDataValues;
};

class DataReply {
public:

    DataReply() { std::cout << "Data reply constructor is called "<< std::endl; }
    ~DataReply() { std::cout << "Data reply destructor is called "<< std::endl; }
    DataReply(const DataReply& ) { std::cout << "Data reply copy constructor is called "<< std::endl; }

    std::vector<ItemDataHistory>& GetItemDataHistories() { return m_vecItemData; }  

private:
    // The list of DataValue
    std::vector<ItemDataHistory> m_vecItemData;
};



void main()
{

    DataValue dv1, dv2, dv3;
    ItemDataHistory itmDH;
    itmDH.GetVecDataValues().reserve(3);
    itmDH.GetVecDataValues().push_back(dv1);
    itmDH.GetVecDataValues().push_back(dv2);
    itmDH.GetVecDataValues().push_back(dv3);

    DataReply dr;
    dr.GetItemDataHistories().reserve(1);
    dr.GetItemDataHistories().push_back(itmDH); // Here copy consturtor of itemdatahistory is called and all data values are copied.
                                                    // Here I want to avoid data values constructor to be called again how can I avoid this
                                                    // How can I directly insert values of dv1, dv2, dv3 into "dr" with out using "itmDH"?
    return;
}

注意这里我不能在 std::vector m_vecItemData 上面使用指针;在数据回复类中,因为这些是来自库的接口类并且无法控制它,我正在调用函数,因此函数可以在数据范围内使用数据

我的问题在上面的代码注释中给出。原因是我有数千个数据值。为了避免调用多个数据值的构造函数,我想将数据值直接插入到数据回复中(即不使用 itmDH 局部变量)

其他问题是

如何在数据回复中保留数据值空间?

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    使用 C++11,您有两种选择:

    • 使您的类型ItemDataHistory 可移动并使用dr.GetItemDataHistories().push_back(std::move(itmDH)); 移动您的数据(如果可能)
    • 查看容器的新成员函数,例如emplace_back()

    【讨论】:

    • ItemDataHistory 可以移动是什么意思?另一个问题是,如果 itmDH 超出范围, dr 仍然包含有效的数据值。谢谢!
    • 谷歌“移动语义 C++”,对于 SO 的 Q/A 格式来说有点过分了。是的,dr 将包含有效值,只要您将 itmDH 复制或移动到其中。
    【解决方案2】:

    C++11中,可以使用移动语义。

    不要这样做:

    itmDH.GetVecDataValues().push_back(dv1);
    itmDH.GetVecDataValues().push_back(dv2);
    itmDH.GetVecDataValues().push_back(dv3);
    

    你可以这样做:

    itmDH.GetVecDataValues().push_back(std::move(dv1));
    itmDH.GetVecDataValues().push_back(std::move(dv2));
    itmDH.GetVecDataValues().push_back(std::move(dv3));
    

    不是复制值,而是将它们简单地移动到向量中。

    而不是复制 itmDH

    dr.GetItemDataHistories().push_back(itmDH);
    

    你也可以移动它:

    dr.GetItemDataHistories().push_back(std::move(itmDH));
    

    此外,您还需要移动构造函数。这是一个例子:

    DataValue(DataValue&& other){
        std::cout << "DataValue move constructor called" << std::endl;
    }
    

    您还可以声明和定义移动赋值运算符:

    DataValue& operator=(DataValue&& other){
        std::cout << "DataValue move assigment operator is called" << std::endl;
        return *this;
    }
    

    为了完全理解移动语义(以及右值引用),请查看以下链接:

    http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html http://thbecker.net/articles/rvalue_references/section_01.html

    【讨论】:

      猜你喜欢
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 2015-01-31
      • 2013-05-31
      • 1970-01-01
      • 2018-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多