C++ 如何重写QObject::findChildren以仅返回派生类型
通过回答我自己的另一个问题(),我发现C++ 如何重写QObject::findChildren以仅返回派生类型,c++,qt,qobject,C++,Qt,Qobject,通过回答我自己的另一个问题(),我发现QObject::findChildren将返回通过reinterpret\u cast的任何子级 我希望重写该行为,以便只获取派生类型 这是因为我有一个复合模式,其中所有项都是相同的基类型,但我希望使用findChildren来查找特定的子类 我尝试按如下方式覆盖findChildren: template <class T> QList<T> Section::findChildren(QString name) { QLi
QObject::findChildren
将返回通过reinterpret\u cast
的任何子级
我希望重写该行为,以便只获取派生类型
这是因为我有一个复合模式,其中所有项都是相同的基类型,但我希望使用findChildren来查找特定的子类
我尝试按如下方式覆盖findChildren:
template <class T>
QList<T> Section::findChildren(QString name)
{
QList<T> siblings = QObject::findChildren<T>(name);
QList<T> children;
for(int i=0; i < siblings.size(); i++)
{
T test = siblings.at(i);
T child = dynamic_cast<T>(test);
if(child)
children << child;
}
return children;
}
模板
QList节::findChildren(QString名称)
{
QList SIBLINES=QObject::findChildren(名称);
QList儿童;
对于(int i=0;i
OP发现他在他的类层次结构中错误地使用了Q_对象
宏。我保留了他在下面接受的原始答案,但正确的答案是必须在基类和派生类中使用Q_对象
宏
原始答案:
如果QObject::findObject()
确实使用了重新解释\u cast
,那么所有对T
的转换都将成功,即使类型无法表示。基于API描述,这毫无意义。但是,假设您在这一点上是正确的,那么您的实现是有缺陷的,因为您得到的同级列表已经是T
点因为重新解释\u cast
,您应该使用QObject
,然后使用dynamic\u cast
删除您想要的实例,如下所示:
template <class T>
QList<T> Section::findChildren(QString name)
{
QList<QObject*> siblings = QObject::findChildren<QObject*>(name);
QList<T> children;
for(int i=0; i < siblings.size(); i++)
{
QObject* test = siblings.at(i);
T child = dynamic_cast<T>(test);
if(child)
children << child;
}
return children;
}
模板
QList节::findChildren(QString名称)
{
QList SIBLINES=QObject::findChildren(名称);
QList儿童;
对于(int i=0;i 由于QObject::findChildren()
的子对象不是虚拟的,您无法覆盖它。您所做的只是对它进行阴影处理。只有在节对象、引用或指针上直接调用该方法时,才会调用该方法。“任何通过重新解释的子对象”-几乎所有的指针都可以用这个钝锤投射到任何其他指针上。感觉你的假设或你没有展示的代码有问题。你能提供一个例子吗?看看实现,QT使用它自己的古怪实现来模拟动态投射
而不是重新解释投射
。也许你不是正确使用其中一个QT宏来设置元对象。Kurt-你说得对。我错误地认为只有基类需要Q_对象宏。我进一步深入研究,可以看到正如你所说的,元对象用于自己进行转换。当我将Q_对象添加到所有子类时,我得到了我期望的行为。谢谢大家!下面是这种行为的原因是qobject\u cast
即使关闭了编译器的RTTI也能工作,例如,为了节省嵌入式系统上的空间。在每个qobject
派生类中,您绝对需要一个Q\u对象
宏。虽然它本不应该是必需的-如果我在所有子类定义中都使用了Q\u对象,我会这样做我看到了我所期望的。