Почему первый блок кода приводит к значению мусора, а второй блок складывает значения членов класса? - PullRequest
2 голосов
/ 16 января 2020

У меня есть класс с именем Person, который имеет имя, 4 переменные a, b, c, d и значение t, которое добавляет a, b, c, d вверх.

Вот код, описывающий мою проблему:

#include <iostream>

using namespace std;
class person {
    public:
    string name;
    int a;
    int b;
    int c;
    int d;
    int t = a + b + c + d;
};

int main() {
    {
        person p;
        cin >> p.name >> p.a >> p.b >> p.c >> p.d;
        cout << p.t << '\n'; // garbage
    }
    {
        person p;
        string s;
        int A, B, C, D;
        cin >> s >> A >> B >> C >> D;
        p = {s, A, B, C, D};
        cout << p.t << '\n'; // prints the sum
    }

    return 0;
}

В первом блоке предположим, что я получаю "Энди", 1, 2, 3, 4 от пользователя, при печати t, он печатает значение мусора. Во втором блоке он печатает t = 10, что я и ожидал, поведение первого блока неожиданно, я не знаю, почему это происходит.

Ответы [ 2 ]

2 голосов
/ 16 января 2020

В первом случае используется инициализатор по умолчанию для t. Хотя, когда t инициализируется через a + b + c + d, элементы a, b, c и d еще не инициализированы. Вы присваиваете значения после создания объекта:

// create object with members not initialized
person p;   
// write values
cin >> p.name >> p.a >> p.b >> p.c >> p.d;
// garbage
cout << p.t << '\n'; // garbage

Средняя линия не имеет значения для того, что вы видите для t, потому что t инициализируется только один раз, перед конструктором работает. Установка других членов позже не влияет на значение t.

Во втором случае вы используете агрегатная инициализация . Поскольку вы предоставляете значения для всех членов, кроме последнего, t будет снова инициализироваться с использованием инициализатора по умолчанию. В этом случае во время инициализации t все остальные члены уже были инициализированы (члены инициализируются в порядке их появления в определении класса). Следовательно, вы видите правильное значение.

0 голосов
/ 16 января 2020

Использование оператора = не создает «правила», что ваш код всегда будет оставаться верным. Например:

int i = 9;  //i = 9
int j = i + 1;  // right now, j == 10

i = 99;     //now, i is equal to 99, but j has not changed.
            // j doesn't retroactively become 100 because of a previous line of code.

Таким образом, в конструкторе по умолчанию t инициализируется как мусор, и ОНА будет оставаться случайным значением мусора, пока не будет записана снова. t = a + b + c + d; не математическая формула. Он выполняется один раз, и t будет держать значение, пока вы не напишите в него снова.

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