Re[3]: Преимущества NVI в C++ (non virtual interface)
От: remark Россия http://www.1024cores.net/
Дата: 29.04.06 19:21
Оценка: 16 (2) +2 :)
Здравствуйте, 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()
{
  // свои действия
}


В этом коде просто нельзя сделать ошибку, т.к. ничего лишнего делать не надо!

Вот и думай после этого об универсальности.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.