Здравствуйте, minorlogic, Вы писали:
M> Но в последнем варианте , мы даем разработчику отнаследованному от нас и возможность исменить поведение как _Foo() так и Foo(), то есть больше свободы , то есть больше универсальности.
Больше универсальности — можно сделать правильно, а можно сделать неправильно. Зашибенская универсальность
Рассмотрим всем нам хорошо известный пример: CDlg::OnInitDialog()
Каких только извращений я не видел при перекрытии этой функции.
И так:
BOOL CMyDlg::OnInitDialog()
{
CDlg::OnInitDialog();
// свои действия
return TRUE;
}
И так:
BOOL CMyDlg::OnInitDialog()
{
// свои действия
CDlg::OnInitDialog();
return TRUE;
}
И так:
BOOL CMyDlg::OnInitDialog()
{
// свои действия
return CDlg::OnInitDialog();
}
И так:
BOOL CMyDlg::OnInitDialog()
{
CDlg::OnInitDialog(); // CMyDlg унаследован не напрямую от CDlg, т.е. таким вызовом пропускаем обработку непосредственного родителя
// свои действия
return TRUE;
}
И все они неправильные! Правильный единственный вариант:
BOOL CMyDlg::OnInitDialog()
{
BOOL res = CParentDlg::OnInitDialog(); // Надо внимательно следить, что бы здесь было имя именно непосредственного родителя
// свои действия
return res; // Исхожу из того предположения, что обычно нет необходимости влиять на отображение фокуса
}
Я и сам так раньше не писал, и сейчас не всегда так пришу, просто потомучто влом. Влом заниматься тем, что меня не касается — вызывать какой-то метод какого-то класса (который ещё к тому же меняется), создавать дополнительную переменную.
Вот тебе и универсальность, о которой ты говоришь, — более половины всех перекрытий функции OnInitDialog(), которые я видел, были неправильные!
Если бы разработчик класса CDlg был примерным мальчиком и слушал Саттера (неважно, что он ещё об этом не написал в том момент
) и сделал бы NVI, то перекрытия функций OnInitDialog() выглядели бы просто так:
void CMyDlg::OnInitDialog()
{
// свои действия
}
В этом коде просто нельзя сделать ошибку, т.к. ничего лишнего делать не надо!
Вот и думай после этого об универсальности.