C++ 将指向子类的指针存储在基类的容器中可以吗
我有一个容器:C++ 将指向子类的指针存储在基类的容器中可以吗,c++,inheritance,C++,Inheritance,我有一个容器: QSet < QDialog*> dialogs_; 我想将指向这些对话框的指针存储在我的“dialogs_uu2;”成员变量中。但现在我遇到了错误: error: invalid conversion from 'QDialog*' to '_1_Dialog*' [-fpermissive] 在这种情况下使用-fppermissive可以吗?还是这是个坏主意? 编辑: 我有一个名为create_uu的fnc,在它的内部我有一个声明: templ
QSet < QDialog*> dialogs_;
我想将指向这些对话框的指针存储在我的“dialogs_uu2;”成员变量中。但现在我遇到了错误:
error: invalid conversion from 'QDialog*' to '_1_Dialog*' [-fpermissive]
在这种情况下使用-fppermissive可以吗?还是这是个坏主意?编辑:
我有一个名为create_uu的fnc,在它的内部我有一个声明:
template<class Dialog,class Caller, class Parent>
Dialog* Main_Dialog::create_(Caller* caller, Parent* parent)
{
return (*dialogs_->insert(new Dialog(caller,parent)));
}
模板
对话框*主对话框::创建(调用者*调用者,父对象*父对象)
{
返回(*对话框->插入(新对话框(调用者、父级));
}
这就是这条线这给了我前面提到的错误您可以将指向派生类的指针存储在包含基类的容器中。但是,您从中得到的是指向基类的指针。然后,通常,您要么只使用基类方法,要么使用dynamic_cast来检查其类型
template<class Dialog,class Caller, class Parent>
Dialog* Main_Dialog::create_(Caller* caller, Parent* parent)
{
return (*dialogs_->insert(new Dialog(caller,parent)));
}
模板
对话框*主对话框::创建(调用者*调用者,父对象*父对象)
{
返回(*对话框->插入(新对话框(调用者、父级));
}
*对话框->插入()是指向基类的指针。您知道它总是指向一个类对话框,但编译器没有,因为您从未告诉过它。试试这个:
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;
}
模板
对话框*主对话框::创建(调用者*调用者,父对象*父对象)
{
Dialog*result=新对话框(调用者、父对象);
对话框->插入(结果);
返回结果;
}
您可以将指向派生类的指针存储在包含基类的容器中。但是,您从中得到的是指向基类的指针。然后,通常,您要么只使用基类方法,要么使用dynamic_cast来检查其类型
template<class Dialog,class Caller, class Parent>
Dialog* Main_Dialog::create_(Caller* caller, Parent* parent)
{
return (*dialogs_->insert(new Dialog(caller,parent)));
}
模板
对话框*主对话框::创建(调用者*调用者,父对象*父对象)
{
返回(*对话框->插入(新对话框(调用者、父级));
}
*对话框->插入()是指向基类的指针。您知道它总是指向一个类对话框,但编译器没有,因为您从未告诉过它。试试这个:
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;
}
模板
对话框*主对话框::创建(调用者*调用者,父对象*父对象)
{
Dialog*result=新对话框(调用者、父对象);
对话框->插入(结果);
返回结果;
}
这是函数内部的代码:
return (*dialogs_->insert(new Dialog(caller,parent)));
^ // Returning Base class pointer
返回(*对话框->插入(新对话框(调用者、父级));
^//返回基类指针
您的返回类型为Dialog*
因此,有一个从基到派生的转换,隐式转换在这里失败。
尝试将dynamic\u cast
转换为对话框指针(从QDialog指针),然后返回。
这是函数内部的代码:
return (*dialogs_->insert(new Dialog(caller,parent)));
^ // Returning Base class pointer
返回(*对话框->插入(新对话框(调用者、父级));
^//返回基类指针
您的返回类型为Dialog*
因此,有一个从基到派生的转换,隐式转换在这里失败。
尝试将dynamic\u cast
转换为对话框指针(从QDialog指针),然后返回。
我还没有(尚未)尝试编写任何针对您的问题的代码,但从架构的角度来看,您的情况是OOP对GUI最常见和最明显的应用:任何小部件(例如)都是小部件的容器(即某些更具体GUI元素的基类)
对我来说奇怪的是,为什么您从两个类派生,一个是公共类(ok),另一个是私有类(可能与对话框有关)
顺便说一句,我认为这是导致您的错误的私有部分:尝试更改为公共。我(尚未)尝试编写针对您的问题的任何代码,但从架构的角度来看,您的情况是OOP在GUI中最常见和最明显的应用:任何小部件(例如)它都是小部件的容器(即某些更具体GUI元素的基类)
对我来说奇怪的是,为什么您从两个类派生,一个是公共类(ok),另一个是私有类(可能与对话框有关)
顺便说一句,我认为这是造成您错误的私人原因:尝试更改为公共。仅供参考,带有\uu
的startig名称是为编译器保留的。您可能永远不会遇到问题,但技术上是不正确的。@ChrisLutz谢谢,是的,我知道这一点,这只是从我的“练习框”中获取的-永远不会在它之外使用。再次感谢。+1您如何存储_1_Dialog类型的对象?@ChrisLutz:不,这将是不一致的。正如程序不能使用为实现保留的名称一样,实现也不允许使用为程序保留的名称。名称以前导下划线开头,后跟其他名称与大写字母相比,不包含双下划线的名称是为程序保留的,而不是在全局命名空间范围内。@ChrisLutz:我当然同意,最好是在安全方面出错。仅供参考,带有\uu
的startig名称是为编译器保留的。您可能永远不会遇到问题,但这是一个错误技术上不正确。@ChrisLutz谢谢,是的,我知道这一点,这只是我的“练习箱”-永远不会在它之外使用。再次感谢。+1您如何存储_1_Dialog类型的对象?@ChrisLutz:不,这将是不一致的。正如程序不能使用为实现保留的名称一样,实现也不允许使用为程序保留的名称。名称以前导下划线开头,后跟其他名称与大写字母相比,不包含双下划线的字母是为程序保留的,而不是在全局命名空间范围内。@ChrisLutz:我当然同意,出于安全考虑犯错更好。但我想指出的是,这可能是一个输入错误,TS希望从创建
返回QDialog
,而不是对话框。@hvd恐怕这没有什么区别,-fpermissive或no go。这一点很好。我希望Main\u Dialog.create\u(调用者,家长)
返回Dialog1*
,但是如果Dialog1
没有提供对调用者有意义的公共成员,那么返回