父子类中的槽函数
父类和子类,我在父类中有一个槽函数,子类中有一个槽函数,名字相同,且在每个类的构造函数中都有同一个信号触发各自的槽函数,会触发哪个?
会触发两个槽函数,父类和子类的都会触发。 哪怕子类中有同名函数,父类构造时还不知道,所以不会连接子类版本。你会得到两个分开的连接:父类的、子类的。
假如虚函数呢?
只会调用父类的槽函数,即使它是虚函数。 在 C++ 中: 虚函数的多态性只在对象构造完成后才有效。 如果你在 父类的构造函数中连接槽函数: 此时 this 指针虽然看起来是子类对象,但构造阶段实际是父类部分在构造,虚函数的多态表(vtable)仍是父类的。 所以:🔹哪怕你在子类中 override 了槽函数,也不会被调用! chatgpt说错了: 假如是虚函数,那么两次都会触发子类版本
假如不在构造函数中呢?
会调用子类中 override 的槽函数。 在 C++ 中,对象构造完成之后,虚函数的多态行为才会启用。 此时调用 connect(sender, SIGNAL(sig()), this, SLOT(onClicked())):
this 是完整构造好的子类对象。
SLOT(onClicked()) 是字符串,Qt 在 runtime 会根据 this 的实际类型(meta-object)去查找 onClicked。
由于子类中 override 了该槽,连接的是子类的版本。
拓展
假如在父类中函数中调用虚函数,会直接调用子类的虚函数吗? 会的,即使你在父类的成员函数中调用虚函数,只要对象是子类的实例,最终会调用子类重写后的虚函数。
拓展2
假如我在子类中connect一个父类: 的槽函数,而且是protected slots的类型,编译器不允许,只有public slots才会被允许,protected规则是子类内调用,前者相当于类外使用了?