Итерация массива объектов

Я пытаюсь создать массив объектов, а затем перебирать его и что-то делать с каждым объектом. Моих знаний C++ недостаточно.

Вот что у меня есть. Я попытался убрать весь бессмысленный код. Что не так, мой объект tr не то, что я ожидаю. Его свойство numOfCars равно 0, поэтому я знаю, что не получаю доступ к объекту поезда, как ожидал.

#include <stdlib.h>

class Train {
    public:
        int numOfCars;
        void init();
        void move();
};

void Train::init() {
    //код намеренно удален
}

void Train::move() {
    //код намеренно удален
}

const int trainCount = 2;
Train train1;
Train train2;
Train trains[trainCount] {train1, train2};

void setup() {  
    Serial.begin(9600);
    train1.numOfCars = 5;
    train1.init();

    train2.numOfCars = 5;
    train2.init();
}

void loop() {
    for(int n = 0; n < trainCount; n++) {
        Train tr = trains[n];
        Serial.println(tr.numOfCars); //всегда печатает 0
        tr.move();    
    }
}

, 👍3


2 ответа


Лучший ответ:

5

Вы создаете не массив ссылок, вы создаете массив из объектов; они копируются. Вы можете увидеть это, переместив строку (и добавив знак равенства)

Train trains[trainCount] = {train1, train2};

в конец метода настройки. Однако это не относится к делу, поскольку вы не полностью используете возможности массивов. Вам не нужно создавать отдельные объекты везде, просто сразу создайте массив объектов с помощью new[] и используйте их. Вот так:

#include <stdlib.h>

class Train {
    public:
        int numOfCars;
        void init();
        void move();
};

void Train::init() {}
void Train::move() {}

const int trainCount = 2;
Train* trains = new Train[trainCount];

void setup() {
    // инициализируем поезда
    for (int i = 0; i < trainCount; ++i) {
        trains[i].numOfCars = 5;
        trains[i].init();
    }
    Serial.begin(9600);
}

void loop() {
    for(int n = 0; n < trainCount; n++) {
        Serial.println(trains[n].numOfCars); //всегда печатает 0
        trains[n].move();    
    }
}
,

Если конструктор Train не зависит от других вещей, инициализируемых в первую очередь (в этом случае вы должны new в setup()), нет смысла использовать динамическое выделение памяти: просто объявите Train trains[trainCount];., @Edgar Bonet


2

Как уже сказал uint128_t, ваша проблема в том, что вы создаете массив копий. Вам действительно следует избегать копирования поездов, особенно если вы собираетесь поместить в них значительный объем данных. Вместо этого просто создайте их один раз в массиве, а затем вы можете либо вызывайте их как члены массива напрямую (например, trains[0].init();) или используйте ссылки.

Например, если вы инициализируете свои поезда следующим образом:

const int trainCount = 2;
Train trains[trainCount];
Train &train1 = trains[0];
Train &train2 = trains[1];

Затем "настоящие" поезда живут в массиве, а train1 и train2 ссылки на них. Остальная часть вашего кода должна нормально работать без изменений. я однако предложил бы избегать копирования поездов в цикле:

void loop() {
    for(int n = 0; n < trainCount; n++) {
        Train &tr = trains[n];        // обратите внимание на '&'!
        Serial.println(tr.numOfCars);
        tr.move();    
    }
}
,