存储2D对象数组的最佳方法是什么?

时间:2013-11-26 07:34:03

标签: c++ multidimensional-array

我想将C ++对象存储在MxN表中,我想创建Object,如:

Vector2D<MyObject*> objects = new Vector2D<MyObject*>(M,N);
MyObject* obj = new MyObject;
objects.add(i,j, obj);

稍后,我应该以类似的方式访问这些项目。 请建议我最好的想法,而不仅仅是方法。我知道的很少。 :)

编辑: 基本上我需要的是,只需为通用对象的MxN网格分配内存。只需添加/检索具有给定行和列的项目。

6 个答案:

答案 0 :(得分:2)

看起来你来自Java或C#领域的C#世界。欢迎。在C ++中,您拥有自动存储对象,并且您不必拥有new所有内容。如果你还有Vector2D类,那就足够了。

Vector2D<MyObject> objects(M,N);
MyObject obj;
objects.add(i,j, obj);

否则,您可以按std::vector制作2D矢量:

std::vector<std::vector<MyObject>> objects;

答案 1 :(得分:1)

最直接的方法是:

vector<vector<MyObject>> objects ;

不幸的是,您必须编写一些代码来将每行初始化为N.

在microsoft channel9网站上有一个很好的讲座,其中Stephan T. Lavavej(是的,他的首字母是STL)正是为解决nurikabe难题所做的。

C9 - STL lecture - Nurikabe solver

答案 2 :(得分:1)

您可以制作2D矢量。参考:std::vector

std::vector<std::vector<MyObject>> objects;

但在使用此对象之前,您应该创建此对象。

// you know the size of your 2D : MaxRow, MaxCol
std::vector<std::vector<MyObject> > objects(MaxRow, 
                               std::vector<MyObject>(MaxCol, MyObject());

或者你可以

std::vector<std::vector<MyObject> > objects;
for(size_t r_i=0; r_i<MaxRow; ++r_i) {
      // create and push a row in the 2D matrix.
      objects.push_back(std::vector<MyObject>());
      for(size_t c_i=0; c_i<MaxCol; ++c_i) {
           // push a col in the new created row.
           objects[r_i].push_back(MyObject());
      }
 }

现在您想要访问矩阵。

size_t row, col;
// now you know your row and col : input or from anywhere

假设您在callObject类中有一个函数MyObject

// you can do this.
objects[row][col].callObject();

但是如果你想存储稀疏矩阵,那么你可以做

std::vector<std::vector<MyObject*>objects(MaxRow, 
                           std::vector<MyObject>(MaxCol, nullptr);
objects[2][3] = new MyObject(/*your arguments*/);

objects[2][3].callObject();

objects[0][0].callObject(); // Boom !!! Null pointer here.

使用指针,std::unique_ptrstd::shared_ptr


如果你想要一个Vector2D类,你可以使用它环绕这个向量向量。

 typedef MyObject T;
 class Vector2D {
      std::vector<std::vector<T> > objects;
      public:
      // initialize the objects with MaxRow rows each with MaxCol cols.
      Vector2D(size_t MaxRow, size_t MaxCol);
      // remember that there should already be somebody at this row or col
      // or you have to create all the rows before this row and all the cols before
      // this col in this row.
      void addItem(size_t row, size_t col, const MyObject & obj);   
 };

我使用typedef int T因为更改模板会更容易。


正如我之前所说,这很大程度上取决于你想要的和你的数据。如果它的稀疏,我会使用指针向量的向量。

 typedef MyObject T;
 class Vector2D {
      std::vector<std::vector<std::unique_ptr<T> > > objects;
      public:
      // initialize the Nullptr with MaxRow rows each with MaxCol cols.
      Vector2D(size_t MaxRow, size_t MaxCol);
      // now you can just add the item, as pointer is already there.
      void addItem(size_t row, size_t col, MyObject * obj);   
 };

使用unique_ptr处理删除和其他引用事项。


你可以通过在Vector2D中继承std::vector< std::vector<T> >来“获得很多其他东西”,但在大多数情况下,组合比继承更好。

答案 3 :(得分:0)

更好地使用STRUCT数组,STRUCT的字段取决于你的MyObject字段的类型

答案 4 :(得分:0)

我会创建一个向量向量并重载所有需要的运算符。所以你可以重用std实现。 但首先要考虑一下,如何访问这个Vector2D。它真的是一个矢量或更好的其他存储类型。

答案 5 :(得分:0)

使用现代C ++ 11编译器,您可以使用内置的arrayinitializer_lists,它看起来像这样:

    #include <array>
    using namespace std;
    ...

    vector<vector<int>> Objects;

    // Initialization
    Objects = {{1,2,3}, {4,4,5}};
    // Iterating
    for ( auto it = Objects.begin(); it != Objects.end(); ++it) {
      // you can access the arrays with *it in here
      for( auto it2 = *it->begin(); it2 != *it->end(); ++it2) {
        // you can access values directly with *it2
        *it2 = 1;
      }
    }

您可以使用auto并让编译器像我一样找出类型,或者您可以指定itit2实际上是向量迭代器。