Давайте предположим, что у нас есть класс B
с member
, который по умолчанию инициализирован как 42
.Этот класс знает, как вывести значение его member
(он делает это в конструкторе):
struct B
{
B() : member(42) { printMember(); }
void printMember() const { std::cout << "value: " << member << std::endl; }
int member;
};
Затем мы добавляем класс A
, который получает константную ссылку на B
ипросит B
напечатать его значение:
struct A
{
A(const B& b) { b.printMember(); }
};
Наконец, мы добавляем еще один класс Aggregate
, который агрегирует A
и B
.Сложность в том, что объект a
типа A
объявлен до объекта b
типа B
, но затем a
инициализируется с помощью (еще не действительной?) Ссылки на b
:
struct Aggregate
{
A a;
B b;
Aggregate() : a(b) { }
};
Рассмотрим вывод создания Aggregate
(я добавил некоторые записи как для конструктора, так и для деструктора A
и B
) ( Попробуйте в сети! ):
a c'tor
value: 0
b c'tor
value: 42
b d'tor
a d'tor
Правильно ли я предполагаю, что инициализация a
недопустимой ссылкой на (еще не действительный) экземпляр b
является неправильной, и, следовательно, это неопределенное поведение?
Мне известен порядок инициализации.Это то, что заставляет меня бороться.Я знаю , что b
еще не создан, но я также думаю , чтобы знать, что будущий адрес b
может быть определен еще до того, как b
будет построен.Поэтому я предположил, что в может быть какое-то правило, о котором я не знаю , которое позволяет компилятору инициализировать b
члены по умолчанию до создания b
или что-то в этом роде.(Было бы более очевидно, если бы первое распечатанное значение было бы чем-то, что выглядит случайным, а не 0
(значение по умолчанию int
)).
Этот ответ помог мне понять, что мне нужно различать
- , связывающий ссылку с неинициализированным объектом (который действителен) и
- , обращающийсяпо ссылке неинициализированный объект (который не определен)