如何仅将派生类型覆盖 QObject::findChildren 到 return
How to override QObject::findChildren to return only the derived type
通过回答我自己的另一个问题 (here),我发现 QObject::findChildren<T>
将 return 任何通过 reinterpret_cast<T>
的 child .
我想重写该行为,以便我只获得派生类型。
这是因为我有一个复合模式,其中所有项目都是相同的基本类型,但我想使用 findChildren 来查找特定的 sub-classes。
我尝试如下覆盖 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;
}
在我的示例中,我说了四个项目 children,两个是一种类型,两个是另一种类型,具有相同的基数 class。我为 T 传递了一种派生类型,正如预期的那样(现在)QObject::findChildren 给出了所有四个 children。但我预计 dynamic_cast 只会成功两次,它会成功四次。
如果我在模板函数之外传递包含四个项目的 returned 列表,我可以成功地将其剔除为我正在寻找的两个项目。
编辑:
OP 发现他在 class 层次结构中错误地使用了 Q_OBJECT
宏。我将在下面留下他接受的原始答案,但正确答案是必须在基础和派生的 classes.
中使用 Q_OBJECT
宏
原始答案:
如果 QObject::findObject()
真的使用了 reinterpret_cast<>
,那么所有对 T
的转换都会成功,即使无法表示类型。根据 API 的描述,这没有任何意义。但是,假设您在这一点上是正确的,那么您的实现是有缺陷的,因为由于 reinterpret_cast<>
,您得到的兄弟姐妹列表已经是 T
指针。相反,您应该使用 QObject
然后使用 dynamic_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;
}
通过回答我自己的另一个问题 (here),我发现 QObject::findChildren<T>
将 return 任何通过 reinterpret_cast<T>
的 child .
我想重写该行为,以便我只获得派生类型。
这是因为我有一个复合模式,其中所有项目都是相同的基本类型,但我想使用 findChildren 来查找特定的 sub-classes。
我尝试如下覆盖 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;
}
在我的示例中,我说了四个项目 children,两个是一种类型,两个是另一种类型,具有相同的基数 class。我为 T 传递了一种派生类型,正如预期的那样(现在)QObject::findChildren 给出了所有四个 children。但我预计 dynamic_cast 只会成功两次,它会成功四次。 如果我在模板函数之外传递包含四个项目的 returned 列表,我可以成功地将其剔除为我正在寻找的两个项目。
编辑:
OP 发现他在 class 层次结构中错误地使用了 Q_OBJECT
宏。我将在下面留下他接受的原始答案,但正确答案是必须在基础和派生的 classes.
Q_OBJECT
宏
原始答案:
如果 QObject::findObject()
真的使用了 reinterpret_cast<>
,那么所有对 T
的转换都会成功,即使无法表示类型。根据 API 的描述,这没有任何意义。但是,假设您在这一点上是正确的,那么您的实现是有缺陷的,因为由于 reinterpret_cast<>
,您得到的兄弟姐妹列表已经是 T
指针。相反,您应该使用 QObject
然后使用 dynamic_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;
}