c++ mfc virtual call concept
От: jyuyjiyuijyu  
Дата: 11.09.11 20:52
Оценка:
Всем привет
в классе CDialog есть виртуальная функция OnInitDialog
при чем при ее переопределении в производных классах ее надо вызывать явно
все равно она там выполняет разный stuff в том числе вызывает DoDataExchange
если ее забыть вызвать ничего не будет работать
virtual BOOL OnInitDialog()
{
    ... // тут забыли __super::OnInitDialog
    ... // а тут уже путь точно не к успеху
}

я попался на этой ошибке я определил
virtual void DoDataExchange(CDataExchange* pDX)
{
    ...
}

чтобы связать контролы CxxCtrl с элеменати управления (static,button,..)
но не вызвал OnInitDialog базового класса из своей OnInitDialog и ничего не работало
НАКОНЕЦ ТО ВОПРОС: почему так сделано ?
можно же было в месте где вызывается виртуальная OnInitDialog
вызывать вместо нее не виртуальную функцию например Dummy она бы
выполняла нужный код
(который сейчас находится в virtual BOOL CDialog::OnInitDialog())
а virtual BOOL CDialog::OnInitDialog сделать пустой заглушкой на случай
если мы не определили свою OnInitDialog а потом Dummy делала бы
(после того как все проинитит) виртуальный вызов нашей OnInitDialog
а если ее нет то вызывалась бы ее пустая заглушка
вот и весь вопрос... почему так нельзя было сделать...?
Re: c++ mfc virtual call concept
От: Centaur Россия  
Дата: 12.09.11 05:41
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>НАКОНЕЦ-ТО ВОПРОС: почему так сделано?

J>Можно же было в месте, где вызывается виртуальная OnInitDialog, вызывать вместо нее невиртуальную функцию, например Dummy. Она бы выполняла нужный код (который сейчас находится в virtual BOOL CDialog::OnInitDialog()), а virtual BOOL CDialog::OnInitDialog сделать пустой заглушкой на случай, если мы не определили свою OnInitDialog, а потом Dummy делала бы (после того как все проинитит) виртуальный вызов нашей OnInitDialog. А если ее нет, то вызывалась бы ее пустая заглушка.
J>вот и весь вопрос... почему так нельзя было сделать...?

Потому что этот путь не спасает от ошибок при иерархиях выше двух этажей и, наоборот, провоцирует их.


В случае же классической схемы, которая ломается сразу, как только программист забыл вызвать родительскую реализацию, программист довольно быстро приучается Всегда вызывать базовую реализацию, кроме Очень Редких и Тщательно Взвешенных особых случаев.
Re: c++ mfc virtual call concept
От: MasterZiv СССР  
Дата: 12.09.11 06:36
Оценка:
On 12.09.2011 0:52, jyuyjiyuijyu wrote:

> НАКОНЕЦ ТО ВОПРОС: почему так сделано ?


Почему сделано так ЧТО ? Почему виртуальные методы предков надо
вызывать руками ? Ну, такой язык С++, нет там :before и :after,
только :around. Как и во многих других объектно-ориентированных
языках с бедной объектной моделью.

В MFC же сделано стандартно для любой С++ -библиотеки.
Posted via RSDN NNTP Server 2.1 beta
Re: c++ mfc virtual call concept
От: _nn_ www.nemerleweb.com
Дата: 12.09.11 07:15
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

А в чем проблема решить это своим классом?
template<typename T, typename Base = CDialog>
class MyDialog : public Base
{
public:
  ...

  virtual BOOL OnInitDialog()
  {
     T* t = static_cast<T*>(this);

     t->BeforeOnInitDialog();
     Base::OnInitDialog();
     t->AfterOnInitDialog();
  }

  void BeforeOnInitDialog() {}
  void AfterOnInitDialog() {}
  ...
}


И все, проблема решена.
Паника не нужна
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: c++ mfc virtual call concept
От: MasterZiv СССР  
Дата: 12.09.11 07:55
Оценка:
On 12.09.2011 0:52, jyuyjiyuijyu wrote:

> НАКОНЕЦ ТО ВОПРОС: почему так сделано ?

> можно же было в месте где вызывается виртуальная OnInitDialog
> вызывать вместо нее не виртуальную функцию например Dummy она бы
> выполняла нужный код
> (который сейчас находится в virtual BOOL CDialog::OnInitDialog())
> а virtual BOOL CDialog::OnInitDialog сделать пустой заглушкой на случай
> если мы не определили свою OnInitDialog а потом Dummy делала бы
> (после того как все проинитит) виртуальный вызов нашей OnInitDialog
> а если ее нет то вызывалась бы ее пустая заглушка
> вот и весь вопрос... почему так нельзя было сделать...?

А, это ... Есть просто код, который нужно в диалоге вызывать ДО
выполнения DDX. Если сделать, как ты говоришь, нужно было бы
делать две фукнции инициализации, до и после DDX, было бы сильно
сложнее схема инициализации.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: c++ mfc virtual call concept
От: jyuyjiyuijyu  
Дата: 12.09.11 12:35
Оценка:
Здравствуйте, Centaur, Вы писали:
да действительно теперь понятно
Re[3]: c++ mfc virtual call concept
От: jyuyjiyuijyu  
Дата: 12.09.11 12:46
Оценка:
благодарю Всех ответивших
Re[2]: c++ mfc virtual call concept
От: jyuyjiyuijyu  
Дата: 12.09.11 15:51
Оценка:
Здравствуйте, _nn_, Вы писали:

__>А в чем проблема решить это своим классом?

в основном конечно лень да и мысли такой не возникало
а как этим пользоваться так ?
struct OptionsDlg : MyDialog<OptionsDlg>
{
    OptionsDlg() : MyDialog<OptionsDlg>(IDD_DIALOG)
    {
    }
    
    void BeforeOnInitDialog()
    {
        // ...
    }
    
    void AfterOnInitDialog()
    {
        // ...
    }
};
Re[2]: c++ mfc virtual call concept
От: jyuyjiyuijyu  
Дата: 12.09.11 15:55
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>А, это ... Есть просто код, который нужно в диалоге вызывать ДО

MZ>выполнения DDX. Если сделать, как ты говоришь, нужно было бы
MZ>делать две фукнции инициализации, до и после DDX, было бы сильно
MZ>сложнее схема инициализации.

да и это тоже..
Re[3]: c++ mfc virtual call concept
От: _nn_ www.nemerleweb.com
Дата: 13.09.11 06:21
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>Здравствуйте, _nn_, Вы писали:


__>>А в чем проблема решить это своим классом?

J>в основном конечно лень да и мысли такой не возникало
J>а как этим пользоваться так ?
J>
J>struct OptionsDlg : MyDialog<OptionsDlg>
J>{
J>    OptionsDlg() : MyDialog<OptionsDlg>(IDD_DIALOG)
J>    {
J>    }
    
J>    void BeforeOnInitDialog()
J>    {
J>        // ...
J>    }
    
J>    void AfterOnInitDialog()
J>    {
J>        // ...
J>    }
J>};
J>


Да, именно так.
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.