标题:
this.instanceMethod1()
在源文件中:
class Clock : public QWidget
{
Q_OBJECT
public:
explicit Clock(QWidget *parent = 0);
......
}
class ElecClock : virtual public Clock
{
Q_OBJECT
public:
explicit ElecClock(QWidget *parent = 0);
private slots:
void showTime(); //display two LCDNumber
......
}
class MechClock : virtual public Clock
{
Q_OBJECT
public:
explicit MechClock(QWidget *parent = 0);
......
}
class NewClock : public MechClock, public ElecClock //combination of Mechclock and ElecClock
{
Q_OBJECT
public:
explicit NewClock(QWidget *parent = 0);
private slots:
void showTime(); //display two LCDNumber
......
}
在main.cpp中:
Clock::Clock(QWidget *parent) :
QWidget(parent)
{
......
}
ElecClock::ElecClock(QWidget *parent) :
Clock(parent)
{
......
connect(timer, SIGNAL(timeout()), this, SLOT(showTime()));
......
}
MechClock::MechClock( QWidget *parent) :
Clock(parent)
{
......
}
NewClock::NewClock(QWidget *parent) :
MechClock(parent), ElecClock(parent), Clock(parent)
{
......
connect(timer, SIGNAL(timeout()), this, SLOT(showTime()));
......
}
我想展示NewClock。但是当我编译时,错误是“无法通过虚拟基础'Clock'将指针转换为基类'QObject'指向派生类'ElecClock'。”
错误发生在moc_ElecClock.cpp中:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
NewClock c;
c.show();
return a.exec();
}
如何解决这个问题?我的构造函数和插槽有什么问题吗? ^
答案 0 :(得分:2)
static_cast
执行此操作:静态强制转换被称为静态,因为对于强制转换所需的内容的计算是在编译时完成的,无论是指针算术还是转换。
然而,当虚拟继承存在时,事情变得有点困难。主要问题是,使用虚拟继承,所有子类共享子对象的同一实例。为了做到这一点,ElecClock
将指向一个``而不是Clock
本身,而Clock
基类对象将在ElecClock
之外实例化。
虽然,在编译时不可能推断出必要的指针算术。它取决于对象的运行时类型。
<强>解决方案强>
您需要RTTI
(运行时类型信息),并且使用RTTI进行强制转换是dynamic_cast
的工作。
<强>安全强>
只要不变量成立,从基数到派生的 static_cast
是安全的。否则结果为undefined behavior
。然而,在大部分大型代码库中强制执行的不变量很少保持不变。
因此,在类似情况下使用static_cast
时,请考虑先放置assert(dynamic_cast<...>(...))
。
答案 1 :(得分:1)
问题来自下面的连接。由于dynamic_cast
工作速度较慢,自动生成的qt_static_metacall
函数使用了static_cast
,在多重继承的情况下无法投射
ElecClock::ElecClock(QWidget *parent) :
Clock(parent)
{
......
---> connect(timer, SIGNAL(timeout()), this, SLOT(showTime()));
......
}
作为解决方案,我可以建议将连接封装到函数中,并且仅当动态和静态类型的对象相同时才调用该函数。否则,您必须删除该行或拒绝多重继承。