Вы можете делегировать работу отдельному классу:
class MyWindow : public Gtk::Window
{
//public: *** EDIT ***
protected:
template <typename LayoutManager>
MyWindow(LayoutManager const& lm)
{
lm.registerLayouts(this);
lm.registerWidgets(this);
}
};
class SubWindow : public MyWindow
{
class LM { /* ... */ };
public:
SubWindow() : MyWindow(LM()) { }
};
(Отредактировано: улучшенный шаблон скрывает от публичных менеджеров компоновки подклассов ...)
В качестве альтернативы,весь класс в виде шаблона (возможно, выше, чем выше) :
template <typename LayoutManager>
class MyWindow : public Gtk::Window
{
public:
MyWindow()
{
LayoutManager lm(*this);
lm.registerLayouts();
lm.registerWidgets();
}
};
class SpecificLayoutManager { /* ... */ };
using SpecificWindow = MyWindow<SpecificLayoutManager>;
Если вам нужен менеджер раскладки для очистки (не знаком с GTK сам ...):
template <typename LayoutManager>
class MyWindow : public Gtk::Window
{
LayoutManager lm;
public:
MyWindow() : lm(*this)
{
lm.registerLayouts();
lm.registerWidgets();
}
virtual ~MyWindow()
{
// still access to lm...
}
};
Важное примечание: во всех вариантах у нас еще нет полностью построенный производный класс - приведение к последнему в менеджерах компоновки, таким образом, недопустимо (экспериментировал с Любопытно повторяющийся шаблон шаблона , но отбросил идею по той же самой причине: необходимо также привести к производному в конструкторе базы).
Редактировать в ответ на комментарии: Aпример того, как можно управлять дополнительными членами подкласса (используя третий вариант выше, класс шаблона один с элементом менеджера компоновки; lm
элемент теперь должен быть protected
):
class SubWindowLayoutManager
{
template <typename>
friend class MyWindow;
friend class SubWindow;
int someMember;
void registerLayouts() { }
void registerWidgets() { }
};
class SubWindow : public MyWindow<SubWindowLayoutManager>
{
void doSomething()
{
lm.someMember = 77;
}
};
Дополнительно новый вариант без шаблонов:
class MyWindow : public Gtk::Window
{
protected:
class LayoutManager
{
public:
virtual void registerLayouts(MyWindow* parent) = 0;
virtual void registerWidgets(MyWindow* parent) = 0;
};
std::unique_ptr<LayoutManager> lm;
MyWindow(std::unique_ptr<LayoutManager> lm)
: lm(std::move(lm))
{
this->lm->registerLayouts(this);
this->lm->registerWidgets(this);
}
};
class SubWindow : public MyWindow
{
class LM : public LayoutManager
{
public:
void registerLayouts(MyWindow* parent) override { }
void registerWidgets(MyWindow* parent) override { }
int someMember;
};
// convenience access function:
inline LM& lm()
{
return *static_cast<LM*>(MyWindow::lm.get());
}
public:
SubWindow() : MyWindow(std::make_unique<LM>()) { }
void doSomething()
{
//static_cast<LM*>(lm.get())->someMember = 77;
lm().someMember = 77;
}
};