我发现,通过回答我自己的另一个问题(here),QObject::findChildren<T>
将返回任何通过reinterpret_cast<T>
的孩子。
我想覆盖行为,以便只获取派生类型。
这是因为我有一个复合模式,其中所有项目具有相同的基本类型,但我想使用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;
}
在我的例子中,我说四个项目是一个子项,两个是一个类型,两个是另一个,具有相同的基类。我为T传递了一个派生类型,并且正如预期的那样(现在)QObject :: findChildren给出了所有四个子节点。但我希望dynamic_cast只能成功两次,它会这样做四次。 如果我在模板函数之外传递返回的四个项目列表,我可以成功地将其剔除到我正在寻找的两个项目中。
答案 0 :(得分:2)
修改强>
OP发现他在类层次结构中错误地使用了Q_OBJECT
宏。我将离开他在下面接受的原始答案,但正确答案是必须在基础和派生类中使用Q_OBJECT
宏。
原始回答:
如果QObject::findObject()
确实使用reinterpret_cast<>
,则即使无法表示类型,所有T
的强制转换也会成功。根据API描述,这没有任何意义。但是,假设你在这一点上是正确的,那么你的实现是有缺陷的,因为你得到的是由于T
而已经reinterpret_cast<>
指针的兄弟姐妹列表。相反,您应该使用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;
}