Объявление массива переменного размера в качестве переменной-члена класса / шаблона - PullRequest
0 голосов
/ 01 апреля 2020

Я пытаюсь написать класс на c ++, который будет содержать переменную-член 2D-массива. Цель этого класса - представить имитированную физическую модель, используя этот массив, и я намеревался написать различные действия, которые я хочу выполнить над массивом, в качестве функций-членов.

Моя проблема заключается в попытке инициализировать массив в класс без жесткого кодирования - в идеале, я хотел бы написать общую программу, чтобы размер массива мог быть введен пользователем во время выполнения, и затем он может быть использован в конструкторе перегрузки для класса. то есть что-то вроде этого:


class Lattice{
public:
    //Overload constructor
    Lattice(int);
private:
    //variables:
    int DimensionSize;
    int lattice[DimensionSize][DimensionSize];
}

Lattice::Lattice(int N){
    DimensionSize = N;
    lattice = new int[DimensionSize][DimensionSize];
}

Я вижу, что приведенный выше код явно не будет работать, так как переменная "DimensionSize" не определена во время выполнения, что означает объем памяти, необходимый для массива 2d " lattice "неизвестно.

Я искал на этом форуме ответ на этот вопрос, но, похоже, что-то прямо не полезное для моей проблемы, и любые другие вопросы, которые были заданы, кажутся вполне старый. Если бы кто-то мог указать мне на решение или сообщить мне, возможно ли то, что я хочу, это было бы очень полезно - интересно, может ли решение использовать вектор вместо массива?

Обновление:

Я смог создать желаемое поведение, используя шаблонный класс:

template <int N>
class Lattice
{
public:
    //Constructor
    Lattice();
    ~ some other functions ~

private:
    float lattice[N][N];
};

template <int N>
Lattice<N>::Lattice() {
    double rando;
//    Initialise the array to a random state.
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++){
            rando = (double)rand() / ((double)RAND_MAX + 1);
            if( rando <= 0.5 ){
                lattice[i][j] = -1.0;
            }
            else if( rando >= 0.5 ){
                lattice[i][j] = 1.0;
            }
        }
    }
}

Я могу видеть, что использование векторов вместо массивов возможно, поэтому у меня сейчас вопрос, есть ли серьезные недостатки использовать шаблон, как указано выше? Я вижу, что объявление и определение класса теперь должны содержаться в одном заголовочном файле, как указано в этой теме Почему шаблоны могут быть реализованы только в заголовочном файле? , но есть ли другие проблемы, которые могут возникать отдельно от этого неудобства?

1 Ответ

0 голосов
/ 01 апреля 2020

Как указано в комментариях, если вы хотите объявить 2D-массив и затем выделить его с помощью new, объявите его следующим образом: int** lattice. Кроме того, я бы порекомендовал объявить его как один массив (или вектор), чтобы все элементы были непрерывными в памяти, а затем вычислить положение элемента, используя x, y и DimensionSize:

class Lattice{
public:
    //Overload constructor
    Lattice(int);
    //access-method
    int getElement(int x, int y)
private:
    //variables:
    int DimensionSize;
    //simple pointer
    int* lattice;
}

Lattice::Lattice(int N){
    DimensionSize = N;
    lattice = new int[DimensionSize*DimensionSize];
}

int Lattice::getElement(int x, int y)
{
    \\calculate the element-position from x and y using DimensionSize
    return lattice[x + y*DimensionSize]; 
}

Так как lattice является приватным членом, вам в любом случае придется определять метод доступа, а наличие всех элементов в памяти может значительно ускорить доступ.

Редактировать: вот код с явным 2d-массив:

class Lattice{
public:
    //Overload constructor
    Lattice(int);
    //access-method
    int getElement(int x, int y)
private:
    //variables:
    int DimensionSize;
    //simple pointer
    int** lattice;
}

Lattice::Lattice(int N){
    DimensionSize = N;
    lattice = new int[DimensionSize][DimensionSize];
}

int Lattice::getElement(int x, int y)
{
    return lattice[x][y]; 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...