Доступ к дочернему атрибуту в родительском конструкторе UB при использовании CTRP? - PullRequest
0 голосов
/ 17 октября 2018

Я сделал wandbox, который фиксирует мою проблему: https://wandbox.org/permlink/qAX6SL43BvERo32Z

По сути, как подсказывает Титл.Я использую CRTP, и мой конструктор базового / родительского класса вызывает дочерний метод стандартным способом в CTRP.

НО этот дочерний метод использует собственные атрибуты дочерних классов, которые, если они имеют определенный тип, такие как std :: string, могут вызывать проблемы во время выполнения (такие как неправильное размещение в MSVC и 'what ():basic_string :: _ M_create '/ пустая строка в GCC).

Короче говоря, это UB?Если так, то почему?

Бонусные баллы для тех, кто может дать советы по решению этой проблемы.Должен ли я добавить виртуальный метод CTRP "Init", который родительский класс вызывает для инициализации дочерних переменных?Стоит ли вообще избегать вызова CTRP дочерних методов в конструкторе?

1 Ответ

0 голосов
/ 17 октября 2018

Доступ к дочернему атрибуту в родительском конструкторе UB

Да, в общем.

... при использовании CTRP?

И, в частности, да.

Если так, то почему?

Поскольку поведение доступа к объекту вне его времени жизни не определено.Время жизни производного объекта и его членов еще не началось к моменту создания объекта base-sub.

Вывод: базы CRTP не должны делать магию CRTP (т. Е. Вы не должны static_cast<Derived*>(this) или аналогичные) в своих конструкторах и деструкторах (и будьте осторожны при вызове функций-членов, поскольку они также не должны делать то же самое).

Бонусные баллы для тех, кто может дать советы о том, как справиться с этимпроблема.Должен ли я добавить виртуальный CTRP-метод «Init», который родительский класс вызывает для инициализации дочерних переменных?

Конструктор производного класса должен инициализировать свои собственные переменные независимо от того, используете вы CRTP или нет.Конструктор не должен делать ничего лишнего, кроме инициализации состояния объекта.Он не должен "приносить плоды".

...