C++ Qt-C++;-使用connect通过父级访问的子级函数

C++ Qt-C++;-使用connect通过父级访问的子级函数,c++,qt,casting,C++,Qt,Casting,如果标题不是很明确,很抱歉。下面是一个示例,classA有几个子级,childA1,childA2等。。存储在classA的列表中: QList<ClassA> listA; listA << childA1() << childA2(); 编译器说classA没有成员start()。 start() connect(this, SIGNAL(signalStart()), listA[0], SLOT(start())); 它正在工作。所以我的问题是,在

如果标题不是很明确,很抱歉。下面是一个示例,
classA
有几个子级,
childA1
childA2
等。。存储在
classA
列表中:

QList<ClassA> listA;
listA << childA1() << childA2();
编译器说
classA
没有成员
start()
start()

connect(this, SIGNAL(signalStart()), listA[0], SLOT(start()));

它正在工作。所以我的问题是,在列表中存储为
classA
之后,他如何知道这个函数
start()
?有没有办法知道“原始”类型?

首先,您应该将对象的指针存储在
QList

然后您可以使用
dynamic\u cast
确定对象的子类型:

A *obj = listA[0];

if (A1 *a1 = dynamic_cast<A1 *>(obj)) {
    // This is an A1 object, you can call start()
    a1->start();
} else if (A2 *a2 = dynamic_cast<A2 *>(obj)) {
    // This is an A2 object
}
A*obj=listA[0];
if(A1*A1=动态_铸造(obj)){
//这是一个A1对象,可以调用start()
a1->start();
}否则如果(A2*A2=动态_铸造(obj)){
//这是一个A2对象
}

首先,您应该将对象的指针存储在
QList

然后您可以使用
dynamic\u cast
确定对象的子类型:

A *obj = listA[0];

if (A1 *a1 = dynamic_cast<A1 *>(obj)) {
    // This is an A1 object, you can call start()
    a1->start();
} else if (A2 *a2 = dynamic_cast<A2 *>(obj)) {
    // This is an A2 object
}
A*obj=listA[0];
if(A1*A1=动态_铸造(obj)){
//这是一个A1对象,可以调用start()
a1->start();
}否则如果(A2*A2=动态_铸造(obj)){
//这是一个A2对象
}

Qt信号/插槽使用内省(能够在运行时列出任何
QObject
的方法和属性)

Qt在C++中利用该工具具有内省能力。您可能想了解有关Qt信号/插槽内部的更多信息

你可以在没有信号/插槽的情况下使用内省。因此,在您的示例中,您不需要定义signal
signalStart()
就可以调用
start()
方法。相反,您可以这样做:

QMetaObject::invokeMethod(listA[0], "start");
这将在指定的
QObject
中查找名为start的函数(无论指针类型如何),并调用它

下面是一个使用内省的完整工作示例:

#include <QtCore>

QTextStream& qOut(){static QTextStream out(stdout); return out;}

class MyObject : public QObject{
    Q_OBJECT
public:
    explicit MyObject(QObject* parent= nullptr):QObject(parent){}
    ~MyObject(){}
    //Object has a slot named func
    Q_SLOT void func(){ qOut() << "Hello func!\n"; }
};

int main(int , char*[]){
    QObject* object = new MyObject();

    //print the object's class name (this is the real class name!)
    qOut() << object->metaObject()->className() << "\n";

    //look for a function named func in the object, and invoke it
    QMetaObject::invokeMethod(object, "func");

    return 0;
}

//run MOC on this CPP file
#include "main.moc"
#包括
QTextStream&qOut(){static QTextStream out(stdout);return out;}
类MyObject:公共QObject{
Q_对象
公众:
显式MyObject(QObject*parent=nullptr):QObject(parent){}
~MyObject(){}
//对象有一个名为func的插槽

Q_SLOT void func(){qOut()Qt信号/插槽使用内省(能够在运行时列出任何
QObject
的方法和属性)

QT利用C++工具中的自省能力,您可能需要查看更多关于QT信号/时隙内部的信息。 您可以在没有信号/插槽的情况下使用内省。因此,在您的示例中,您不需要定义信号

signalStart()
就可以调用
start()
方法。相反,您可以执行以下操作:

QMetaObject::invokeMethod(listA[0], "start");
这将在指定的
QObject
中查找名为start的函数(无论指针类型如何),并调用它

下面是一个使用内省的完整工作示例:

#include <QtCore>

QTextStream& qOut(){static QTextStream out(stdout); return out;}

class MyObject : public QObject{
    Q_OBJECT
public:
    explicit MyObject(QObject* parent= nullptr):QObject(parent){}
    ~MyObject(){}
    //Object has a slot named func
    Q_SLOT void func(){ qOut() << "Hello func!\n"; }
};

int main(int , char*[]){
    QObject* object = new MyObject();

    //print the object's class name (this is the real class name!)
    qOut() << object->metaObject()->className() << "\n";

    //look for a function named func in the object, and invoke it
    QMetaObject::invokeMethod(object, "func");

    return 0;
}

//run MOC on this CPP file
#include "main.moc"
#包括
QTextStream&qOut(){static QTextStream out(stdout);return out;}
类MyObject:公共QObject{
Q_对象
公众:
显式MyObject(QObject*parent=nullptr):QObject(parent){}
~MyObject(){}
//对象有一个名为func的插槽
Q_槽空函数(){qOut()