Всем привет
в классе CDialog есть виртуальная функция OnInitDialog
при чем при ее переопределении в производных классах ее надо вызывать явно
все равно она там выполняет разный stuff в том числе вызывает DoDataExchange
если ее забыть вызвать ничего не будет работать
virtual BOOL OnInitDialog()
{
... // тут забыли __super::OnInitDialog
... // а тут уже путь точно не к успеху
}
чтобы связать контролы CxxCtrl с элеменати управления (static,button,..)
но не вызвал OnInitDialog базового класса из своей OnInitDialog и ничего не работало
НАКОНЕЦ ТО ВОПРОС: почему так сделано ?
можно же было в месте где вызывается виртуальная OnInitDialog
вызывать вместо нее не виртуальную функцию например Dummy она бы
выполняла нужный код
(который сейчас находится в virtual BOOL CDialog::OnInitDialog())
а virtual BOOL CDialog::OnInitDialog сделать пустой заглушкой на случай
если мы не определили свою OnInitDialog а потом Dummy делала бы
(после того как все проинитит) виртуальный вызов нашей OnInitDialog
а если ее нет то вызывалась бы ее пустая заглушка
вот и весь вопрос... почему так нельзя было сделать...?
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>НАКОНЕЦ-ТО ВОПРОС: почему так сделано? J>Можно же было в месте, где вызывается виртуальная OnInitDialog, вызывать вместо нее невиртуальную функцию, например Dummy. Она бы выполняла нужный код (который сейчас находится в virtual BOOL CDialog::OnInitDialog()), а virtual BOOL CDialog::OnInitDialog сделать пустой заглушкой на случай, если мы не определили свою OnInitDialog, а потом Dummy делала бы (после того как все проинитит) виртуальный вызов нашей OnInitDialog. А если ее нет, то вызывалась бы ее пустая заглушка. J>вот и весь вопрос... почему так нельзя было сделать...?
Потому что этот путь не спасает от ошибок при иерархиях выше двух этажей и, наоборот, провоцирует их.
Пусть CDialog::Dummy выполняет необходимую инициализацию CDialog и вызывает виртуальную OnInitDialog (с пустой реализацией в CDialog).
Далее, пусть MyBaseDialog : public CDialog переопределяет OnInitDialog, чтобы там выполнять какую-то свою инициализацию, и не вызывает реализацию, предоставленную CDialog (всё равно же она пустая).
Наконец, пусть MyDerivedDialog : public MyBaseDialog также переопределяет OnInitDialog, и тоже не вызывает базовую реализацию (все же привыкли, что в OnInitDialog можно базовую реализацию не вызывать).
Результат: бабушкина реализация в CDialog::Dummy отрабатывает, внучкина реализация в MyDerivedDialog отрабатывает, мамина реализация в MyBaseDialog не отрабатывает.
В случае же классической схемы, которая ломается сразу, как только программист забыл вызвать родительскую реализацию, программист довольно быстро приучается Всегда вызывать базовую реализацию, кроме Очень Редких и Тщательно Взвешенных особых случаев.
On 12.09.2011 0:52, jyuyjiyuijyu wrote:
> НАКОНЕЦ ТО ВОПРОС: почему так сделано ?
Почему сделано так ЧТО ? Почему виртуальные методы предков надо
вызывать руками ? Ну, такой язык С++, нет там :before и :after,
только :around. Как и во многих других объектно-ориентированных
языках с бедной объектной моделью.
В MFC же сделано стандартно для любой С++ -библиотеки.
On 12.09.2011 0:52, jyuyjiyuijyu wrote:
> НАКОНЕЦ ТО ВОПРОС: почему так сделано ? > можно же было в месте где вызывается виртуальная OnInitDialog > вызывать вместо нее не виртуальную функцию например Dummy она бы > выполняла нужный код > (который сейчас находится в virtual BOOL CDialog::OnInitDialog()) > а virtual BOOL CDialog::OnInitDialog сделать пустой заглушкой на случай > если мы не определили свою OnInitDialog а потом Dummy делала бы > (после того как все проинитит) виртуальный вызов нашей OnInitDialog > а если ее нет то вызывалась бы ее пустая заглушка > вот и весь вопрос... почему так нельзя было сделать...?
А, это ... Есть просто код, который нужно в диалоге вызывать ДО
выполнения DDX. Если сделать, как ты говоришь, нужно было бы
делать две фукнции инициализации, до и после DDX, было бы сильно
сложнее схема инициализации.
Здравствуйте, _nn_, Вы писали:
__>А в чем проблема решить это своим классом?
в основном конечно лень да и мысли такой не возникало
а как этим пользоваться так ?
Здравствуйте, MasterZiv, Вы писали:
MZ>А, это ... Есть просто код, который нужно в диалоге вызывать ДО MZ>выполнения DDX. Если сделать, как ты говоришь, нужно было бы MZ>делать две фукнции инициализации, до и после DDX, было бы сильно MZ>сложнее схема инициализации.
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>Здравствуйте, _nn_, Вы писали:
__>>А в чем проблема решить это своим классом? J>в основном конечно лень да и мысли такой не возникало J>а как этим пользоваться так ? J>