Здравствуйте, sharez, Вы писали:
S>Но есть нюанс. Если мы хотим дать программисту (или 3-rd parties) наследоваться от Button, то нам обязательно придется ему вталдычить, чтобы он не забывал вызывать fill() после создания своей кнопки. А это печаль в некотором роде, потому что программистам обязательно захочется отнаследоваться для случая Button < ToolbarButton чтобы банально разом для всех кнопок указать высоту и ширину.
А если попробовать заюзать какой-нить NVI-паттерн?
Т.е. типа сделать в верхнем базовом классе какой-нить ShowButton, который показывает кнопку. Причем сделать его невиртуальным, ибо все равно там простенький функционал в стиле показать\скрыть, и перекрывать его все равно никто не будет, ибо не зачем.
А вот это non virtual ShowButton, будет уже вызывать тот самый виртуальный fill, который запросит атрибуты (цвета там или что там было).
Т.е. нечто вида
//где-то в CButton есть метод виртуальный
virtual void fill();//или GetColor - чего там было то?
CButton::ShowButton(BOOL bShow)
{
if (bShow)//если показываем кнопку
fill();//то вызываем внутри виртуальный метод, который все сначала запросит
CWidget::ShowButton(bShow);//ну а это какая-то простенькая вещь: показать скрыть кнопку
}
Т.е. таким образом мы явно провоцируем последующих кодеров (разработчиков наследников от CButton), вызывать невиртуальный метод показа кнопки. А вот он уже вызывает нужный виртуальный fill, т.к. фактически объект к моменту вызова ShowButton уже полностью создан, отработали все конструкторы всей иерархии.
Костыль конечно, но по крайней мере явный. Без ShowButton ничего нет в UI (не видно), звать обязательно. А вот оно уже всю неочевидную инициализацию завершит.