5

Является ли следующее определение?Циклическая зависимость в списке инициализации конструктора

class A; 
class B; 

// define A, which takes B& in constructor 
// define B, which takes A& in constructor 

class C 
{ 
    A a; 
    B b; 
public: 
    C() : a(b), b(a) { /* stuff with a and b */ } 
} 

Полный пример: ideone.com.

Это безопасно/четко определено, если конструкторы для A и B ничего не делают со ссылками, которые они получают?

+1

Почему downvote? Дайте мне знать, как я могу улучшить этот вопрос. – Claudiu

+0

Я не думаю, что компилятор позволяет вам выполнить 'a (b)', потому что когда 'a' инициализируется,' b' еще не инициализируется. – user3528438

+0

@ user3528438: Он уверен, что пример ideone компилируется и запускается. Но это потому, что мне повезло или потому, что он хорошо определен в стандарте? – Claudiu

ответ

2

N4140 [class.cdtor]/1 гласит:

Для объекта с нетривиальным конструктором, со ссылкой на любой нестатический член или базовый класс объекта перед конструктором начинает результаты выполнения в неопределенном поведении. Для объекта с нетривиальным деструктором , ссылаясь на любой нестатический член или базовый класс объекта после завершения выполнения деструктора , результат приводит к неопределенному поведению.

Хотя этот отрывок сам по себе не означает, что поведение в противном случае четко определено, следующий пример показывает, что это так. Вот отрывок:

struct B : public A { int j; Y y; }; // non-trivial 
extern B bobj; 
B* pb = &bobj; // OK 

Так что ответ: да, поведение в вашем случае хорошо определенно, если вы не со ссылкой на член или базовые классы b в конструкторе A.

+0

Это достаточно интуитивно понятно. Таким образом, [user3528438's example] (https://ideone.com/V5uPyr) является неопределенным поведением, потому что «m_a.m_value» обращается до запуска конструктора 'm_a'. Спасибо, что выкопали ссылку! – Claudiu

+0

@Claudiu Правильно, это определенно UB. –

+0

Можете ли вы привязать * ссылку * к объекту, который еще не был создан? Существуют различия между семантикой указателей и ссылок. Например, 'int * p = nullptr; int & r = * p; 'считается UB, но' int * r = &*p; ', возможно, не UB (C явно разрешает его, например). – dyp

Смежные вопросы