Проверьте время компиляции, что класс наследует от базового класса, и используйте его как - PullRequest
0 голосов
/ 26 апреля 2020

Название вопроса не очень понятно, я постараюсь объяснить лучше. Я использую Qt и windows Я работаю с производным (прямо или косвенно) от QWidget. Мой windows должен обрабатываться единообразно, чтобы я мог взять указатель на текущее активное окно и вызвать для него методы, не зная фактического класса окна, по этой причине все мои windows являются производными от другого класса, давайте назовем его «Мой ЭкранПО». Пока все хорошо.

Теперь я хотел бы обработать в "myScreen" также скрытие и отображение окна, чтобы оно было однородным. Например, переход из одного окна в другое может означать вызов «hide ()» в текущем окне и «show ()» в новом окне. Поскольку «myScreen» и QWidget не имеют никакого отношения, я должен использовать dynamic_cast для приведения windows, который, как мне известно, происходит от «myScreen» и «QWidget» внутри методов «myScreen», чтобы просто вызывать функции QWidget упомянутый.

Я знаю, что, вероятно, наилучшим способом могло бы быть использование myScreen, производного от QWidget, и всех других windows, производных от этого, но моя цель - как можно меньше изменить существующий код. Я также пытался использовать виртуальное наследование, но этот подход не может работать из-за файлов, автоматически сгенерированных mo c (см. Эту ссылку Невозможно преобразовать указатель в базовый класс в указатель на производный класс ).

К настоящему времени мне удалось убедиться, что конструктор myScreen вызывается классом, производным от QWidget:

struct isQWidget{
    class QWidgetType{
        QWidgetType(){}
        friend struct isQWidget;
    };
    template<class T>
    static QWidgetType isQwidgetType(const T&){
        static_assert (std::is_base_of<QWidget, T>::value, "Error: not a QWidget");
        return QWidgetType();
    }
};

Объявление конструктора:

myScreen(myScreen& parentScreen, isQWidget::QWidgetType);

Определение конструктора:

sigin::sigin(QWidget *parent, myScreen& si) :
    QWidget(parent),
    myScreen(si, isQWidget::isQwidgetType(*this)),
    ui(new Ui::sigin)
{
    ui->setupUi(this);
}

Я хотел бы рассматривать указатель на myScreen как указатель на QWidget во время компиляции «myScreen», поскольку я знаю, что всегда буду использовать что-то, производное от QWidget.

Есть идеи, как мне справиться с этой проблемой?

1 Ответ

0 голосов
/ 27 апреля 2020

Я имел в виду нечто подобное

template <typename T>
myScreen::myScreen(T &parent)
{
    static_assert(std::is_base_of<QWidget, T>::value, "Error: not a QWidget");
    QWidget &parentQt = dynamic_cast<QWidget&>(parent); // guaranteed to succeed in runtime by the above
    ...
}

Так что для родителя, который не наследуется от QWidget, это будет ошибкой компиляции, и которое всегда будет успешно приведено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...