Виртуальная конструкторская идиома - добродетельная или полная ошибка - PullRequest
3 голосов
/ 11 декабря 2010

Одним из золотых правил в C ++ является то, что время жизни экземпляра начинается, когда его конструктор завершается успешно, и заканчивается, когда начинается его деструктор.

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

Идиома виртуального конструктора, как упомянуто в C ++ FAQ 20.8 , по-видимому, указывает на обратное.

Мой вопрос:

  • Какое точное определение в стандарте для определения времени жизни объектов относительно вызовов их конструкторов и деструкторов?
  • и, кроме того, действителен так называемый «виртуальный конструктор Idom»?

Ответы [ 2 ]

7 голосов
/ 11 декабря 2010

Я думаю, что вы путаете две разные (если смутно связанные) вещи.

  1. Хорошо известно, что не следует вызывать виртуальные функции из конструкторов (прямо или косвенно) по причинам, обсуждаемым здесь .
  2. То, о чем идет речь в FAQ, - это вызов конструктора из виртуальной функции. В некотором смысле это противоположность # 1. Идея состоит в том, чтобы выбрать конструктор (то есть класс) на основе динамического типа некоторого существующего объекта.
2 голосов
/ 11 декабря 2010

Объект существует как тип класса, к которому принадлежит конструктор, когда конструктор запускается, объект может просто находиться в несогласованном состоянии (что нормально, так как выполнение в настоящее время находится внутри одного из методов объекта).То есть объект, который на самом деле имеет тип Derived, который наследуется от Base, рассматривается как конструкторы Base в Base;this в любом Base::Base() рассматривается как Base *, независимо от фактического типа объекта, на который указывает this.Вызов виртуальных методов это нормально.В конструкторе будут вызываться виртуальные методы для класса конструктора, а не для фактического типа объекта.

Ваш первый вопрос рассматривается в " Базовом классе в списке инициализации производногокласс 'конструктор копирования".Краткий ответ: он описан в п. 12.7 2-3 C ++ 03.

Идиома виртуального конструктора полностью допустима.

...