Virtual member call in constructor. Плохо?
От: Аноним  
Дата: 30.10.07 14:25
Оценка:
Привет всем.

Может и простенький вопрос, но мне не понятно:
чем плох вызов виртуального метода из конструктора?

Спасибки
Re: Virtual member call in constructor. Плохо?
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 30.10.07 14:34
Оценка: 10 (2) +1
Здравствуйте, <Аноним>, Вы писали:

А>Может и простенький вопрос, но мне не понятно:

А>чем плох вызов виртуального метода из конструктора?
Эта проблема называется "потерей указателя this". В наследнике переопределенный метод может обратиться к полю класса (this.*), считая, что совершает вполне легальное действие, в то время как конструктор, быть может, еще не успел инициализировать данное поле (в зависимости от кода конструктора) — и вылетит исключение обращения по пустой ссылке, к примеру. В общем случае конструктор не должен "терять this" (делать его доступным кому-либо) вплоть до своего завершения.
Re: Virtual member call in constructor. Плохо?
От: denezuela Россия  
Дата: 30.10.07 14:39
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Привет всем.


А>Может и простенький вопрос, но мне не понятно:

А>чем плох вызов виртуального метода из конструктора?

А>Спасибки


Скорее всего, дело в том, что пока не выполнились все конструкторы, объект полностью не сконструирован, а следовательно таблица виртуальных функций (или что там в net framework) не полностью загружена в память, и виртуальность не может быть корректно разрешена, по крайней мере так дело обстоит с С++.
Re[2]: Virtual member call in constructor. Плохо?
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 30.10.07 14:47
Оценка: 2 (1)
Все гадости, которые только можно совершить в конструкторе, описаны в статье Теория и практика Java: Методы безопасного конструирования. Не позволяйте указателю "this" пропадать во время конструирования — .NET/Java не принципиально.
Re[3]: Virtual member call in constructor. Плохо?
От: Аноним  
Дата: 30.10.07 14:50
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Все гадости, которые только можно совершить в конструкторе, описаны в статье Теория и практика Java: Методы безопасного конструирования. Не позволяйте указателю "this" пропадать во время конструирования — .NET/Java не принципиально.


Спасибо. Полезная для меня инфа.
Re[2]: Virtual member call in constructor. Плохо?
От: Mab Россия http://shade.msu.ru/~mab
Дата: 30.10.07 14:51
Оценка: +2
Здравствуйте, denezuela, Вы писали:

D>по крайней мере так дело обстоит с С++.

В .NET CLR оно обстоит иначе.
Re[2]: Virtual member call in constructor. Плохо?
От: _FRED_ Россия
Дата: 30.10.07 14:52
Оценка:
Здравствуйте, denezuela, Вы писали:

А>>Может и простенький вопрос, но мне не понятно:

А>>чем плох вызов виртуального метода из конструктора?

D>Скорее всего, дело в том, что пока не выполнились все конструкторы, объект полностью не сконструирован, а следовательно таблица виртуальных функций (или что там в net framework) не полностью загружена в память, и виртуальность не может быть корректно разрешена, по крайней мере так дело обстоит с С++.


Здесь не так Тут именно что поля могут быть ещё непроинициализированы.
Help will always be given at Hogwarts to those who ask for it.
Re[3]: Virtual member call in constructor. Плохо?
От: Аноним  
Дата: 30.10.07 15:02
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здесь не так Тут именно что поля могут быть ещё непроинициализированы.


А разве инициализация полей дефолтовыми значениями происходит не до выполнения конструктора?
Re[4]: Virtual member call in constructor. Плохо?
От: Mab Россия http://shade.msu.ru/~mab
Дата: 30.10.07 15:04
Оценка: 6 (1)
Здравствуйте, Аноним, Вы писали:
А>А разве инициализация полей дефолтовыми значениями происходит не до выполнения конструктора?
Происходит. Вопрос не этом, а в том, что возможна производному классу нужна более сложная инициализация, которую выполняет еще не вызванный конструктор.
Re[3]: Virtual member call in constructor. Плохо?
От: Аноним  
Дата: 30.10.07 15:08
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Все гадости, которые только можно совершить в конструкторе, описаны в статье Теория и практика Java: Методы безопасного конструирования. Не позволяйте указателю "this" пропадать во время конструирования — .NET/Java не принципиально.


Исходя из статьи следует, что проблемы могут возникнуть только при многопоточности.
Я уже понял, что это плохая практика, но всё же интересно: однопоточному приложению это ничем не грозит?
Re[5]: Virtual member call in constructor. Плохо?
От: vladpol Украина http://vlad-mislitel.livejournal.com/
Дата: 30.10.07 15:09
Оценка:
Здравствуйте, Mab, Вы писали:

Mab>Здравствуйте, Аноним, Вы писали:

А>>А разве инициализация полей дефолтовыми значениями происходит не до выполнения конструктора?
Mab>Происходит. Вопрос не этом, а в том, что возможна производному классу нужна более сложная инициализация, которую выполняет еще не вызванный конструктор.
Можно ли тогда сказать, что вызов виртальных методов в конструкторе, не есть плохо, но к этому надо подходить внимательно?
С уважением, Владислав Полищук
Re[4]: Virtual member call in constructor. Плохо?
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 30.10.07 15:12
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Исходя из статьи следует, что проблемы могут возникнуть только при многопоточности.

Не следует, прочитайте внимательнее.

А>Я уже понял, что это плохая практика, но всё же интересно: однопоточному приложению это ничем не грозит?

Грозит.
Re[6]: Virtual member call in constructor. Плохо?
От: _FRED_ Россия
Дата: 30.10.07 15:18
Оценка:
Здравствуйте, vladpol, Вы писали:

V>Можно ли тогда сказать, что вызов виртальных методов в конструкторе, не есть плохо,


Имхо, есть, но этого часто попросту не избежать (изменение свойства "Property" формы в InitializeComponent часто приводит к вызову виртуального метода "OnPropertyChanged" :о()

V>но к этому надо подходить внимательно?


Да
Help will always be given at Hogwarts to those who ask for it.
Re[6]: Virtual member call in constructor. Плохо?
От: Mab Россия http://shade.msu.ru/~mab
Дата: 30.10.07 15:18
Оценка:
Здравствуйте, vladpol, Вы писали:

V>Можно ли тогда сказать, что вызов виртальных методов в конструкторе, не есть плохо, но к этому надо подходить внимательно?

ИМХО да.
Re[4]: Virtual member call in constructor. Плохо?
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 30.10.07 15:20
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>А разве инициализация полей дефолтовыми значениями происходит не до выполнения конструктора?

Не до завершения родительского конструктора.
Re[6]: Virtual member call in constructor. Плохо?
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 30.10.07 15:20
Оценка: 1 (1)
Здравствуйте, vladpol, Вы писали:

V>Можно ли тогда сказать, что вызов виртальных методов в конструкторе, не есть плохо, но к этому надо подходить внимательно?

Это есть плохо и надо выжигать каленым железом. Сколь ни подходи внимательно, если указатель this опубликован, то... кто-нибудь да когда-нибудь его попытается дернуть раньше времени. И это может сделать вовсе не сам внимательный автор класса, не сам внимательный автор всей библиотеки, не самый внимательнейший автор движка или системы — а кто-то, кто не знает, о том что все они (а кое-то из них по-дурости совершенно сознательно), даже будучи внимательными, заложили в свою систему риск безопасности инициализации.
Это как ружье, что висит на стене в первом акте спектакля...
Re[6]: Virtual member call in constructor. Плохо?
От: _FRED_ Россия
Дата: 30.10.07 15:27
Оценка:
Здравствуйте, vladpol, Вы писали:

V>…но к этому надо подходить внимательно?


Гхм… А к чему можно подходить "не внимательно"? Просто, про это надо держать в голове, как и сотню других мелочей…
Help will always be given at Hogwarts to those who ask for it.
Re: Virtual member call in constructor. Плохо?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 30.10.07 15:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Может и простенький вопрос, но мне не понятно:

А>чем плох вызов виртуального метода из конструктора?

Do not call overridable methods in constructors
Re[2]: Virtual member call in constructor. Плохо?
От: _FRED_ Россия
Дата: 30.10.07 15:51
Оценка:
Здравствуйте, nikov, Вы писали:

А>>Может и простенький вопрос, но мне не понятно:

А>>чем плох вызов виртуального метода из конструктора?

N>Do not call overridable methods in constructors


Толку от этого — чуть, часто проблемы это вызывает именно во всяких "компонентах", свойства которых любят отправлять события об их, свойств, изменении, а в производных классах свойства меняются и события "отлавливаются"
Help will always be given at Hogwarts to those who ask for it.
Re: Virtual member call in constructor. Плохо?
От: vdimas Россия  
Дата: 02.11.07 11:16
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Привет всем.


А>Может и простенький вопрос, но мне не понятно:

А>чем плох вызов виртуального метода из конструктора?

Плох тем, что класс-наследник может обратиться к чему угодно в этом переопределённом методе, в т.ч. к своим еще непроинициализированным полям.

Тем не менее, дизайнеры форм и компонентов генерят метод InitializeComponent, который вызывается из конструктора, и который, в свою очередь, вызывает тонны виртуальных методов или обращается к виртуальным св-вам. Об этом надо помнить, при переопределении виртуальных св-в у Control и его наследников. Иногда я прибегаю к услугам ISupportInitialize, как к более общему решению (которое накрывает и эту проблему в т.ч.)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.