Можно ли хранить указатель на дочерний класс в контейнере для базового класса? - PullRequest
1 голос
/ 17 декабря 2011

У меня есть контейнер:

QSet < QDialog*> dialogs_;  

И у меня есть несколько диалогов, которые наследуются от QDialog, например:

class _1_Dialog : public QDialog, private Ui::_1_Dialog
{};  
class _2_Dialog : public QDialog, private Ui::_1_Dialog
{};  

и я хотел бы сохранить указатели на эти диалоги в моем члене 'dialogs_' var. Но теперь я получаю сообщение об ошибке:

error: invalid conversion from 'QDialog*' to '_1_Dialog*' [-fpermissive]  

Было бы нормально использовать -fpermissive в этом случае, или это плохая идея?
EDIT:
У меня есть fnc с именем create_ и внутри его тела у меня есть утверждение:

    template<class Dialog,class Caller, class Parent>
Dialog* Main_Dialog::create_(Caller* caller, Parent* parent)
{
    return (*dialogs_->insert(new Dialog(caller,parent)));
}

так что это строка
что дает мне вышеупомянутую ошибку

Ответы [ 3 ]

1 голос
/ 17 декабря 2011

Вы можете хранить указатели на производные классы в контейнерах, содержащих базовые классы.Тем не менее, вы получаете указатель на базовый класс.Затем вы, как правило, либо используете только методы базового класса, либо используете dynamic_cast, чтобы проверить его тип на самом деле.

template<class Dialog,class Caller, class Parent>
Dialog* Main_Dialog::create_(Caller* caller, Parent* parent)
{
    return (*dialogs_->insert(new Dialog(caller,parent)));
}

* диалогов _-> insert () - указатель на базовый класс. Вы знаете, что он всегда будет указывать на класс Dialog, а компилятор - нет, потому что вы никогда этого не говорили.Попробуйте это:

template<class Dialog,class Caller, class Parent>
Dialog* Main_Dialog::create_(Caller* caller, Parent* parent)
{
    Dialog* result = new Dialog(caller,parent);
    dialogs_->insert(result);
    return result;
}
0 голосов
/ 17 декабря 2011

Я (пока) не пытался написать какой-либо код, специфичный для вашей проблемы, но с архитектурной точки зрения ваши ситуации это наиболее распространенное и очевидное применение ООП к GUI: любой виджет (например) это контейнер виджетов (т.е. базовый класс какого-то более конкретного элемента GUI) ...

Что странного для меня, почему вы унаследовали 2 класса, один общедоступный (хорошо) и частный (может быть, связанный с диалогом)?

Кстати, я думаю, что это частная часть, которая вызывает вашу ошибку: попробуйте перейти к общедоступным.

0 голосов
/ 17 декабря 2011

Это ваш код внутри функции:

return (*dialogs_->insert(new Dialog(caller,parent)));
        ^ // Returning Base class pointer

И ваш тип возврата имеет значение Dialog *

Следовательно, выполняется приведение из Base TO Derived, и здесь неявное приведение не выполняется.

Попробуйте dynamic_cast на указатель диалога (из указателя QDialog) и затем вернитесь.

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