组织私有成员矢量<vector <type>&gt; </vector <type>的接口的最佳方法

时间:2014-12-07 18:59:21

标签: c++ c++11 vector iterator stdvector

假设,我有一个班级:

class Class
{
private:
   std::vector <std::vector <Type>> vec2d;
   // Or, for example, something like this:
   std::vector <std::vector <std::shared_ptr <Type>> vec2dptr;
}

我需要组织一个私有向量的接口。矢量的大小可能会增加数千个元素。什么是最佳解决方案(内存/性能)?

作为变体,我可以从getter(begin(),end())返回一对迭代器:

std::pair <std::vector <const std::vector <const Type>>::iterator,
           std::vector <const std::vector <const Type>>::iterator>
           GetPrimaryVectorRange();

// To get an element from sub-vector, pass iterator of main vector to getter
std::pair <std::vector <const Type>::iterator,
           std::vector <const Type>::iterator>
           GetSecondaryVectorRange(
           std::vector <const std::vector <const Type>>::const_iterator primary_elem );

最简单的方法是通过常量值返回向量,但是然后将调用复制构造函数,而不是从C ++ 11移动构造函数,我是对的吗?在这种情况下是否有任何标准的方法或模式?

1 个答案:

答案 0 :(得分:2)

你的API返回一对std::vector迭代器已经让你公开知道你的2d数组的行是std::vector s,所以你可以保持它简单并做类似的事情

std::vector<Type> const &operator[](size_t i) const { return vec2d[i]; }
std::vector<Type> &operator[](size_t i) { return vec2d[i]; }

如果需要迭代器,让调用者自己提取迭代器:

auto row = arr[i];
auto iter = std::find(row.begin(), row.end(), 42);

如果数组的所有行长度相同,请考虑编写一个简单的2D数组类(或使用mine)来分配一个块中的所有内存。性能会更好,特别是在您想迭代数组的每个元素的情况下。 (我认为C ++应该在标准中包含这样的类。)

编辑:我意识到我的解决方案与您的解决方案相比确实有一个弱点。如果您决定对所有行使用一个巨大的std::vector而不是单独的std::vector,那么它不会破坏基于迭代器的API,但它会破坏我的版本。

另一个选择是返回raw一对原始指针而不是迭代器。它们在迭代器所做的所有相同的地方工作。这仍然会暴露行连续存储的事实,因此您永远不会将单行的元素存储在链表中。但在我看来,连续存储是如此基础,对于任何关心性能的事情都非常重要,因此在API中公开连续性是完全没问题的。

但是,如果它适用于您的需求,我仍然认为使用2D数组包装类是最佳解决方案。