C ++ - векторный двухмерный массив объектов - PullRequest
1 голос
/ 30 июля 2010

Как и предполагалось здесь Я исправил свой двумерный массив чисел, чтобы он работал с классом Vector.

Заголовочный файл:

#include <vector>

typedef std::vector<int> Array;
typedef std::vector<Array> TwoDArray;

И вот как этоused:

TwoDArray Arr2D; 

// Add rows
for (int i = 0; i < numRows; ++i) {
    Arr2D.push_back(Array());
}

// Fill in test data
for (int i = 0; i < numRows; i++) {    
    for (int j = 0; j < numCols; j++) {
        Arr2D[i].push_back(ofRandom(0, 10));           
    }
}

// Make sure the data is there
for (int i = 0; i < numRows; i++) {    
    for (int j = 0; j < numCols; j++) {
        std::cout << Arr2D[i][j] << ' ';
    }
std::cout << '\n';
}

Мой вопрос: как я могу сделать то же самое для пользовательских объектов вместо целых чисел?Я попытался изменить int с помощью MyObject и использовать push_back (new MyObject ());но он не работает должным образом, когда я пытаюсь получить доступ к его функциям.

Заранее спасибо.

Ответы [ 6 ]

1 голос
/ 30 июля 2010

Поскольку вы ищете лучший подход к проектированию, почему бы не последовать совету C ++ FAQ Lite и сделать свой массив плотным (а не рваным).Вы не ожидаете, что вам придется обрабатывать строки разного размера, не так ли?

#include <iostream>
#include <random>
#include <vector>

template<typename T>
class TwoDArray {
        std::vector<T> data;
        const size_t cols;
public:
        TwoDArray(size_t R, size_t C) : data(R*C), cols(C) {}
        T operator()(size_t r, size_t c) const { return data[cols*r+c]; }
        T& operator()(size_t r, size_t c) { return data[cols*r+c]; }
};

int main()
{
        // Make it
        const size_t numRows = 10;
        const size_t numCols = 10;
        TwoDArray<int> Arr2D(numRows, numCols);

        // Fill in test data
        std::random_device rd;
        std::mt19937 eng(rd());
        std::uniform_int_distribution<> unif(0,9);
        for (size_t i=0; i<numRows; ++i)
           for (size_t j=0; j<numCols; ++j)
                Arr2D(i,j) = unif(eng);

        // Make sure the data is there
        for (size_t i = 0; i < numRows; i++) {
            for (size_t j = 0; j < numCols; j++) {
                 std::cout << Arr2D(i,j) << ' ';
            }
            std::cout << '\n';
        }

}

Или вы можете даже сделать размер частью типа, как std::array.

1 голос
/ 30 июля 2010

Если бы я был вами, я бы использовал массив указателей вместо самих объектов (но вам придется позаботиться об освобождении, прежде чем выполнять свой "clear ()").

typedef std::vector<std::vector<myObject* > > 2DArray;

2DArray A;
for (int i=0; i<numRows;++i) A.push_back(std::vector<myObject* >(numColumns));

myObject* M = new myObject(...);
A[row][column] = M;
1 голос
/ 30 июля 2010

Попробуйте это:

template<class T>
struct Array2D {
    vector<vector<T>> Array;
};

теперь вы можете объявить это любому объекту, например

Array2D<MyObject>::Array array;

или даже

Array2D<MyObject*>::Array array;

и продолжай свой день как обычно ...

Помните, что когда вы назначаете объект контейнеру stl, он должен реализовать конструктор по умолчанию без аргументов, конструктор копирования и оператор перегрузки = (const и non-const), в противном случае вы должны вставить указатель на объект .

1 голос
/ 30 июля 2010

new MyObject() вернет указатель на вновь созданный экземпляр класса MyObject.Если вы создали vector<MyObject>, вам нужно сделать что-то вроде push_back(MyObject()).

1 голос
/ 30 июля 2010

вам нужно изменить

typedef std::vector<int> Array;
typedef std::vector<Array> TwoDArray;

до

typedef std::vector<MyObject> Array;
typedef std::vector<Array> TwoDArray;
0 голосов
/ 30 июля 2010

В общих чертах:

struct MyObject {};

typedef std::vector<MyObject> Array;
typedef std::vector<Array> TwoDArray;

// stuff

Arr2D[i].push_back( MyObject() );  

Обратите внимание, что для хранения вещей в векторе они должны быть копируемыми и назначаться.

...