Почему объявление атрибута структуры и порядок инициализации ведут себя так? - PullRequest
0 голосов
/ 28 мая 2018

Я недавно сталкивался с этим:

#include <iostream>
#include <vector> 
#include <string>
#include <algorithm>  //sort function
#include <functional> //functions utilities
#include <random>     //random numbers generation

using namespace std;
default_random_engine         generator;
uniform_int_distribution<int> distribution(0,9999);
auto randomer = bind(distribution, generator);


struct Test_struct {
    string  ord_as_string;
    int     ord;
    Test_struct() :
      ord(randomer()),
      ord_as_string(to_string(ord))
    {}
};

int main() {
  vector<Test_struct> my_vector;
  for(int i = 0; i < 100;  ++i) my_vector.push_back(Test_struct());
  for(auto& e: my_vector)
    cout << e.ord_as_string << " -> " << e.ord << endl;
}

, который печатает следующую последовательность:

142 -> 0
0 -> 1315
1315 -> 7556
7556 -> 4586
4586 -> 5327
5327 -> 2189
2189 -> 470
470 -> 6788
6788 -> 6792
...

Это не имеет смысла, так как структуры int и string атрибуты должны ссылаться на один и тот же логический номер.Поэтому я просто изменил объявление на:

 struct Test_struct {
    int     ord;
    string  ord_as_string;
    Test_struct() :
      ord(randomer()),
      ord_as_string(to_string(ord))
    {}
};

Я подумал, что оно имеет какое-то отношение к порядку объявления атрибутов struct, и оно сработало:

0 -> 0
1315 -> 1315
7556 -> 7556
4586 -> 4586
5327 -> 5327
2189 -> 2189
470 -> 470
6788 -> 6788
...

Итак, могукто-то объяснит мне почему ссылка на ord сохраняется в следующих инициализациях структур, когда она объявляется после другого атрибута, но инициализируется раньше?

Редактировать: Хорошо, элементы инициализируютсяв порядке декларирования, как сказано в комментариях, тогда почему он был разработан таким образом?Это не имеет смысла для меня.

1 Ответ

0 голосов
/ 28 мая 2018

Вы столкнулись с неопределенным поведением.Порядок инициализации членов должен соответствовать порядку объявления.

Поскольку это не так, наблюдаемое вами поведение проистекает из того, что элемент ord неинициализирован и по совпадению повторно использует одно и то же место в памяти на каждой итерации цикла.Это местоположение содержит значение, которое вы присвоили в итерации ранее.

Вы можете прочитать здесь , каков порядок инициализации и почему это так.Чтобы суммировать и ссылку, и комментарии: деструктор должен уничтожать объекты в обратном порядке инициализации, и поскольку может быть несколько конструкторов, должен быть один источник истины, который является порядком объявления в классе.

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