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对象,我会这样做我看到了我所期望的。