Создание вектора векторов (2D-массив) внутри класса - Ошибка: C ++ требует спецификатора типа для всех объявлений - PullRequest
1 голос
/ 01 июня 2019

Итак, я процедурно запрограммировал способ интегрирования уравнений с использованием метода Рунге-Кутта 4 (RK4) в C ++. В настоящее время я пытаюсь создать класс RK4, чтобы добавить больше функциональности в мою программу. Однако, когда я настраиваю свои 2D-массивы в классе, я получаю ошибку «C ++ требует спецификатора типа для всех объявлений», которую я не получил в исходной программе.

Сначала я использовал пространство имен std; однако я наткнулся на ответ, в котором говорилось, что это плохая практика программирования, поэтому я стер эту строку и вместо этого вызвал std :: vector. Я также включил векторную библиотеку, но безрезультатно.

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <vector>

class RK4 {
public:
    RK4(double x_i, double y_i, double z_i, double vx_i, double vy_i, double vz_i);
    //time-related stuff
    double dt = 0.01;
    int numtimes = 1000;

    int numvar = 3;
    double mu = 398589590898200.0;

    //setting up variables
    std::vector<vector<double> > position(numtimes,vector<double>(numvar));
    std::vector<vector<double> > velocity(numtimes,vector<double>(numvar));
    std::vector<vector<double> > rk1(numtimes,vector<double>(numvar));
    std::vector<vector<double> > rk2(numtimes,vector<double>(numvar));
    std::vector<vector<double> > rk3(numtimes,vector<double>(numvar));
    std::vector<vector<double> > rk4(numtimes,vector<double>(numvar));
    std::vector<vector<double> > vk1(numtimes,vector<double>(numvar));
    std::vector<vector<double> > vk2(numtimes,vector<double>(numvar));
    std::vector<vector<double> > vk3(numtimes,vector<double>(numvar));
    std::vector<vector<double> > vk4(numtimes,vector<double>(numvar));

Вот так я без проблем построил код в моей исходной программе:

#include <iostream>
#include <ostream>
#include <cmath>
#include <vector>

using namespace std;

int main(){
// time related things
    //double t_i = 0; // initial time
    double dt = 0.01; // time step
    int numtimes = 10000; // how many steps taken

    vector<vector<double> > position(numtimes,vector<double>(numvar));
    vector<vector<double> > velocity(numtimes,vector<double>(numvar));

    vector<vector<double> > rk1(numtimes,vector<double>(numvar));
    vector<vector<double> > rk2(numtimes,vector<double>(numvar));
    vector<vector<double> > rk3(numtimes,vector<double>(numvar));
    vector<vector<double> > rk4(numtimes,vector<double>(numvar));
    vector<vector<double> > vk1(numtimes,vector<double>(numvar));
    vector<vector<double> > vk2(numtimes,vector<double>(numvar));
    vector<vector<double> > vk3(numtimes,vector<double>(numvar));
    vector<vector<double> > vk4(numtimes,vector<double>(numvar));
}

Я не совсем уверен, почему этот вызов работал в моей исходной (процедурной) программе, но не в моей текущей программе.

Ответы [ 3 ]

1 голос
/ 01 июня 2019

С классами вы не можете инициализировать членов вне функций. Вы можете назначить их в конструкторе.

Кроме того, вы написали "вектор" в нескольких местах, где вам нужен "std :: vector". Это должно исправить это:

#include <math.h>
#include <stdio.h>
#include <iostream>
#include <vector>

class RK4 {
   public:
    RK4(double x_i, double y_i, double z_i, double vx_i, double vy_i, double vz_i) {
        double dt = 0.01;
        int numtimes = 1000;

        int numvar = 3;
        double mu = 398589590898200.0;

        //assigning the vectors
        position = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
        velocity = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
        rk1 = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
        rk2 = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
        rk3 = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
        rk4 = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
        vk1 = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
        vk2 = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
        vk3 = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
        vk4 = std::vector<std::vector<double> >(numtimes, std::vector<double>(numvar));
    }
    //time-related stuff
    double dt = 0.01;
    int numtimes = 1000;

    int numvar = 3;
    double mu = 398589590898200.0;

    //declaring vectors
    std::vector<std::vector<double> > position;
    std::vector<std::vector<double> > velocity;
    std::vector<std::vector<double> > rk1;
    std::vector<std::vector<double> > rk2;
    std::vector<std::vector<double> > rk3;
    std::vector<std::vector<double> > rk4;
    std::vector<std::vector<double> > vk1;
    std::vector<std::vector<double> > vk2;
    std::vector<std::vector<double> > vk3;
    std::vector<std::vector<double> > vk4;
};

int main() {
    RK4 r(1, 1, 1, 1, 1, 1);

    return 0;
}
0 голосов
/ 01 июня 2019

Переместите эти std::vector инициализации в конструктор RK4 и используйте синтаксис списка инициализации члена для их инициализации:

#include <iostream>
#include <vector>

class RK4 
{
    double dt = 0.01;
    int numtimes = 1000;
    int numvar = 3;
    double mu = 398589590898200.0;

    //declaring vectors
    std::vector<std::vector<double> > position;
    std::vector<std::vector<double> > velocity;
    std::vector<std::vector<double> > rk1;
    std::vector<std::vector<double> > rk2;
    std::vector<std::vector<double> > rk3;
    std::vector<std::vector<double> > rk4;
    std::vector<std::vector<double> > vk1;
    std::vector<std::vector<double> > vk2;
    std::vector<std::vector<double> > vk3;
    std::vector<std::vector<double> > vk4;

   public:
    RK4(double x_i, double y_i, double z_i, double vx_i, double vy_i, double vz_i) : 
       position(numtimes, std::vector<double>(numvar)),
       velocity(numtimes, std::vector<double>(numvar)),
       rk1(numtimes, std::vector<double>(numvar)),
       rk2(numtimes, std::vector<double>(numvar)),
       rk3(numtimes, std::vector<double>(numvar)),
       rk4(numtimes, std::vector<double>(numvar)),
       vk1(numtimes, std::vector<double>(numvar)),
       vk2(numtimes, std::vector<double>(numvar)),
       vk3(numtimes, std::vector<double>(numvar)),
       vk4(numtimes, std::vector<double>(numvar))
    {}
};

Учитывая порядок переменных-членов, вы также можете сделать это (но для этого необходимо, чтобы position было объявлено перед любым другим вектором):

#include <iostream>
#include <vector>

class RK4 
{
    double dt = 0.01;
    int numtimes = 1000;
    int numvar = 3;
    double mu = 398589590898200.0;

    //declaring vectors
    std::vector<std::vector<double> > position;
    std::vector<std::vector<double> > velocity;
    std::vector<std::vector<double> > rk1;
    std::vector<std::vector<double> > rk2;
    std::vector<std::vector<double> > rk3;
    std::vector<std::vector<double> > rk4;
    std::vector<std::vector<double> > vk1;
    std::vector<std::vector<double> > vk2;
    std::vector<std::vector<double> > vk3;
    std::vector<std::vector<double> > vk4;

   public:
    RK4(double x_i, double y_i, double z_i, double vx_i, double vy_i, double vz_i) : 
       position(numtimes, std::vector<double>(numvar)),
       velocity(position),
       rk1(position),
       rk2(position),
       rk3(position),
       rk4(position),
       vk1(position),
       vk2(position),
       vk3(position),
       vk4(position)
    {}
};

Причина, по которой это работает, заключается в том, что position и все другие векторы имеют одинаковый размер и начинаются с одинаковых значений. Так что немного проще инициализировать другие векторы с помощью position. Но опять же, это требует, чтобы position было объявлено в классе, прежде чем другие векторы будут работать.

0 голосов
/ 01 июня 2019

В функции вы можете использовать круглые скобки для передачи параметров в конструктор для переменной.Это не работает при указании значений по умолчанию для переменных-членов.Вы должны использовать равномерную инициализацию .

 std::vector<std::vector<double>> position{numtimes, std::vector<double>(numvar)};

Этот синтаксис - использование фигурных скобок - также работает при объявлении переменных, и вы можете использовать эту же строку в main для объявленияposition переменная.

Еще одна вещь, которую вы получаете при равномерной инициализации, - это более строгая безопасность типов.Вы не можете указать число, которое не будет соответствовать тому, где вы пытаетесь его сохранить.Проблема в вашем коде в том, что numtimes - это int, но первый параметр конструктора для vector - это size_t - некоторая форма unsigned.Поэтому вам нужно изменить объявление для numtimes на

unsigned numtimes = 10000;

Обратите внимание, что вам нужно поставить std:: перед всеми vector использованиями.

...