Я искал все ошибки компилятора, которые, по-видимому, вызывает мой дизайн. Все ответы и исправления имеют смысл, но я дошел до того, что исправление одной вещи вызывает еще одну плохую вещь.Как лучше реализовать мой шаблон дизайна C++?
Мой проект на C++ становится все больше и больше, поэтому я пытаюсь обобщить свою проблему, чтобы воспользоваться опытными разработчиками на C++.
Программное обеспечение, которое я пишу, представляет собой XML-парсер, который создает объекты пользовательского интерфейса во время выполнения. Я разработал ContainerInterface
для различных типов контейнеров, которые я хочу использовать. Например, TabWidget
является подклассом QTabWidget
и он также наследует ContainerInterface
. На данный момент это AbsoluteWidget
, TreeWidget
и TabWidget
. Все имеющие реализации для следующих чисто виртуальных функций, определенных в ContainerInterface
:
virtual PushButton* createButton(const QString& label, const QString& define, const QPoint& topLeft, const QSize& size) = 0;
virtual CheckBox* createCheckBox(const QString& label, const QString& define, const QString& header, const QPoint& topLeft, const QSize& size) = 0;
virtual ComboBox* createComboBox(const QString& label, const QString& define, const QString& header, const QPoint& topLeft, const QSize& size) = 0;
virtual Image* createImage(const QString& file, const QString& define, const QPoint& topLeft, const QSize& size) = 0;
virtual Led* createLed(const QString& define, const QString& onColor, const QString& offColor, const QPoint& topLeft, const QSize& size) = 0;
virtual Text* createText(const QString& define, const QString& label, const QPoint& topLeft, const QSize& size) = 0;
Таким образом, в анализаторе я могу использовать ContainerInterface
, например:
void XmlReader::readCheckBox(ContainerInterface* container, const QString& header)
{
Q_ASSERT(xml.isStartElement() && xml.name() == "checkbox");
QXmlStreamAttributes attr = xml.attributes();
CheckBox* checkBox = container->createCheckBox(getLabel(attr), getDefine(attr), getHeader(attr, header), getTopLeft(attr), getSize(attr));
m_centralWidget->setUIElement(getDefine(attr), checkBox); //this is why i need a return value anyway
}
Это спасло меня много кода и работ хороший. Поэтому я хотел бы, чтобы ContainerInterface
также:
virtual TabWidget* createTabWidget(const QPoint& topLeft, const QSize& size) = 0;
virtual TreeWidget* createTreeWidget(const QStringList& labels, const QPoint& topLeft, const QSize& size) = 0;
А теперь мы подошли к той части, где я с трудом: это потребуется осуществление createTabWidget
в TabWidget
и так далее (и это хорошо, потому что Я мог бы иметь Tabwidget
, включенный в Tabwidget
, сам включенный в другой TabWidget
). Если я использую ту же конструкцию, что я использовал для других элементов (например, CheckBox
), заносить бы указатель на новый TabWidget
:
TabWidget* TabWidget::createTabWidget(const QPoint& topLeft, const QSize& size)
{
return new TabWidget(topLeft, size);
}
Это дает мне реальную отладку трудное время, так что это поднимает несколько вопросы:
- Возможно ли верхние
TabWidget::createTabWidget
? (без них он строит отлично) - Должен ли я включать файлы для контейнеров, например.
tabwidget.h
в интерфейсе контейнера, чтобы избежать круговых ограничений? (это дает мнеexpected class name before '{' token
) - Нужно ли мне переслать объявление
TabWidget
вTreeWidget
? (это дает мне ошибкуinvalid use of incomplete type
)
Парсер XML, который вы ищете, поставляется с Qt ('QUiLoader'), и вы можете использовать его во время выполнения. Почему вы пишете еще один? См. [Этот ответ] (http://stackoverflow.com/a/19327470/1329652) для полного примера. –
У вас, похоже, много методов, созданных вручную для конкретного класса. Они не нужны. Вы можете использовать механизм 'QMetaObject' для автоматического определения аргументов конструктора класса для данного типа' QObject' и автоматически сопоставить их с XML. –
Несмотря на то, что я сомневаюсь, что любой мог угадать все цели разбора xml для создания объектов пользовательского интерфейса, на это так много ответов. Я иду: потому что это моя работа. – tobilocker