А правда, что виртуальную функцию нельзя вызывать из конструкторов и деструкторов? У меня такая ситуация, что моя переопределённая функция невызывается если вызов её происходит из конструктора базового класса — я был очень удивлён! Бывает такое или это какой-то баг?
Durs
Re: Виртуальная функция
От:
Аноним
Дата:
07.12.01 09:39
Оценка:
Здравствуйте Yuri Dursin, Вы писали:
YD>А правда, что виртуальную функцию нельзя вызывать из конструкторов и деструкторов? У меня такая ситуация, что моя переопределённая функция невызывается если вызов её происходит из конструктора базового класса — я был очень удивлён! Бывает такое или это какой-то баг?
Когда ты вызываешь виртуальную функцию из конструктора базового класса, вызывается, соотвественно, функция БАЗОВОГО класса, т.к. на момент вызова класса-потомка еще не существует. В случае деструктора ситуация похожая — класса-потомка уже не существует. Так что все корректно.
Здравствуйте Yuri Dursin, Вы писали:
YD>А правда, что виртуальную функцию нельзя вызывать из конструкторов и деструкторов? У меня такая ситуация, что моя переопределённая функция невызывается если вызов её происходит из конструктора базового класса — я был очень удивлён! Бывает такое или это какой-то баг?
Это не баг, потому что таблица виртуальных функций инициализируется в конструкторе наследованного класса, а до этого выполняется конструктор базового. Следовательно вызов виртуальной функции из конструктора некорректен.
Здравствуйте Yuri Dursin, Вы писали:
YD>А правда, что виртуальную функцию нельзя вызывать из конструкторов и деструкторов? У меня такая ситуация, что моя переопределённая функция невызывается если вызов её происходит из конструктора базового класса — я был очень удивлён! Бывает такое или это какой-то баг?
Здравствуйте sasha, Вы писали:
S>Это не баг, потому что таблица виртуальных функций инициализируется в конструкторе наследованного класса, а до этого выполняется конструктор базового. Следовательно вызов виртуальной функции из конструктора некорректен.
Небольшое уточнение: вызов корректен, просто нужно понимать, что ты вызываешь. А вообще вот ссылка на сайт, где объясняется данный вопрос (правда на английском языке) http://www.parashift.com/c++-faq-lite/strange-inheritance.html#[23.3]. Кстати, очень рекомендую.
Здравствуйте Yuri Dursin, Вы писали:
YD>А правда, что виртуальную функцию нельзя вызывать из конструкторов и деструкторов? У меня такая ситуация, что моя переопределённая функция невызывается если вызов её происходит из конструктора базового класса — я был очень удивлён! Бывает такое или это какой-то баг?
есть такая штука как инициализирующий конструктор
функция которая вополняет некую инициализацию недоступную из конструктора
Здравствуйте Андрей, Вы писали:
А>Здравствуйте Yuri Dursin, Вы писали:
YD>>А правда, что виртуальную функцию нельзя вызывать из конструкторов и деструкторов? У меня такая ситуация, что моя переопределённая функция невызывается если вызов её происходит из конструктора базового класса — я был очень удивлён! Бывает такое или это какой-то баг?
А>Почитай http://www.rsdn.ru/forum/message.asp?mid=13047
Здравствуйте VladD2, Вы писали:
YD>>>А правда, что виртуальную функцию нельзя вызывать из конструкторов и деструкторов? У меня такая ситуация, что моя переопределённая функция невызывается если вызов её происходит из конструктора базового класса — я был очень удивлён! Бывает такое или это какой-то баг?
А>>Почитай http://www.rsdn.ru/forum/message.asp?mid=13047
В VC++6 есть опция компилятора, указывающая, как вызывать виртуальные методы в кторе.
/vd0 (Disable Construction Displacements)
на закладке "C++", категория "C++ Language"
По умолчанию — объект создается постепенно, так, что конструктор каждого предка имеет дело с целостным экземпляром своего типа. Соответственно, с VMT предка.
Вызов перекрытого виртуального метода открывает доступ к еще неинициализированным данным, и тем самым опасен.
А может, пересмотреть архитектуру?
Например, использовать двухступенчатое конструирование.
Здравствуйте Кодт, Вы писали:
К>Здравствуйте VladD2, Вы писали:
YD>>>>А правда, что виртуальную функцию нельзя вызывать из конструкторов и деструкторов? У меня такая ситуация, что моя переопределённая функция невызывается если вызов её происходит из конструктора базового класса — я был очень удивлён! Бывает такое или это какой-то баг?
А>>>Почитай http://www.rsdn.ru/forum/message.asp?mid=13047
К>В VC++6 есть опция компилятора, указывающая, как вызывать виртуальные методы в кторе. К>/vd0 (Disable Construction Displacements) К>на закладке "C++", категория "C++ Language"
К>По умолчанию — объект создается постепенно, так, что конструктор каждого предка имеет дело с целостным экземпляром своего типа. Соответственно, с VMT предка.
К>Вызов перекрытого виртуального метода открывает доступ к еще неинициализированным данным, и тем самым опасен.
К>А может, пересмотреть архитектуру? К>Например, использовать двухступенчатое конструирование.
Я уже как-то предлагал тоже самое для деструкторов (где это более актуально). Но все скептически почмокали губами и сказали что все равно нас никто слушать не будет.
Короче, жду когда в C# добавят шаблоны.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.