Еще могу добавить, что изначальная задача поставлена неверно.
Вы пытаетесь написать конструктор базового класса так, что бы он подошел на все случаи жизни - то есть его код без работал без изменений для потомков.
Но ведь когда мы создаем экземпляр класса потомка, мы вызываем именно его (потомка) конструктор. Так почему бы все что нужно изменить в поведении конструктора по отношению к родительскому не добавить в конструкторе потомка.
А если позволить в конструкторе родителя вызвать перегруженный потомком метод, то он получается будет вызван до вызова конструктора потомка. А если мы там инициализируем переменные, выделяем память для каких-либо внутренних структур, которые нужны для работы нашего перегруженного метода? Таким образом придется писать каждый перегруженный метод в стиле defensive programming, обрабатывая все возможные ошибки связанные с неинициализированными полями.
А как раз смысл конструктора в классе (по Страуструпу) - ГАРАНТИРОВАТЬ всем остальным методам класса, что на момент их вызова объект полностью проинициализирован.
Использование виртуальных функций в конструкторе.
-
- Уже с Приветом
- Posts: 660
- Joined: 01 Aug 2002 08:09
-
- Новичок
- Posts: 44
- Joined: 21 Mar 2003 12:44
Hamster wrote:
Порядок по-моему такой:
- Выделяется память
- VFT заполняется указателями на функции базового класса ( в моем примере, класс А )
- Вызывается конструктор A::A
- VFT перезаписывается указателями на функции субкласса ( B )
- Вызывается конструктор B::B
Вам придется вводить несколько конструкторов и вызывать в разных случаях разные конструкторы, или передавать какой-нибудь флаг, чтобы сказать конструктору, что ему делать.
VFT вообще не используется в конструкторах, здесь виртуальные функции просто вызывается как обычные (невиртуальные). Поэтому и нет смысла строить VFT в run-time, что привело бы к потере эффективности, указатель на таблицу виртуальных функций определяется классом и он всегда известен на момент вызова конструктора.
Вообще-то использование виртуальных функций в конструкторах врядли можно назвать хорошей идеей, это может запутать и вас и ваших колег, так что лучше сделайте как-то по другому, воспользуйтесь паттерном фабрики класса если ваши объекты создаются только в куче (можно конечно создать через фабрику класса объект и в стеке но это немного сложнее).
-
- Уже с Приветом
- Posts: 7759
- Joined: 18 Sep 2001 09:01
- Location: RUS.76 -> KOR -> RUS.53 -> US.PA -> US.MD
Возможно, вы будете еще раз неприятно удивлены, но и в деструкторах тоже не вызываются виртуальные методвы. По той же причине, только наоборот - объект уже частично разрушен (начиная с потомков к базам). Так шта....
N.E.R.V.O.U.S.: Networked Electronic Replicant Viable for Observation and Ultimate Sabotage.
-
- Уже с Приветом
- Posts: 4468
- Joined: 21 Sep 2000 09:01
- Location: Sammamish, WA
Sergei VP wrote:VFT вообще не используется в конструкторах, здесь виртуальные функции просто вызывается как обычные (невиртуальные). Поэтому и нет смысла строить VFT в run-time, что привело бы к потере эффективности, указатель на таблицу виртуальных функций определяется классом и он всегда известен на момент вызова конструктора...
Виртуальную функцию можно вызвать в конструкторе (или деструкторе) не напрямую, а через вызов невиртуальной функции-члена класса, которая в свою очередь уже будет вызывать виртуальную функцию "нормальным" образом - т.е через vptr. Поэтому хочется или нет, а vptr должен быть разумным способом проинициализирован к моменту начала конструктора класса. То, что реализовано в популярных компиляторах является вполне разумным и логичным вариантом.
Cheers