无法从指向基 class 的指针转换为指向派生 class 的指针
Cannot convert from pointer to base class to pointer to derived class
在headers中:
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
......
}
在源文件中:
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()));
......
}
在main.cpp中:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
NewClock c;
c.show();
return a.exec();
}
我想展示NewClock。但是当我编译时,错误是 "cannot convert from pointer to base class 'QObject' to pointer to derived class 'ElecClock' via virtual base 'Clock'."
错误发生在moc_ElecClock.cpp:
void ElecClock::qt_static_metacall(QObject *_o, QMetaObject::Call _c,int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
ElecClock *_t = static_cast<ElecClock *>(_o); // this line
Q_UNUSED(_t)
switch (_id) {
case 0: _t->showTime(); break;
default: ;
}
}
Q_UNUSED(_a);
}
如何解决这个问题?我的构造函数和插槽有什么问题吗?
^
static_cast
这样做:静态转换被称为静态,因为转换所需的计算是在 编译时 完成的,无论是指针算法或转化。
然而,当虚拟继承存在时,事情就变得有点困难了。主要问题是,对于虚拟继承,所有子classes 共享同一个子对象实例。为了做到这一点,ElecClock
将有一个指向 `` 的指针,而不是 Clock
本身,并且 Clock
基础 class 对象将在 ElecClock
.
尽管如此,在编译时不可能推导出必要的指针算法。这取决于对象的运行时类型。
解决方案
您需要 RTTI
(运行时类型信息),使用 RTTI 进行转换是 dynamic_cast
的工作。
安全
static_cast
从基到派生是安全的,只要不变量成立。否则结果为 undefined behavior
。然而,对大型代码库的广泛部分强制执行的不变量很少保持不变。
所以在类似情况下使用static_cast
时,考虑把assert(dynamic_cast<...>(...))
放在前面。
问题来自下面的连接。由于 dynamic_cast
运行速度较慢,因此使用了自动生成的 qt_static_metacall
函数 static_cast
在多重继承的情况下无法转换
ElecClock::ElecClock(QWidget *parent) :
Clock(parent)
{
......
---> connect(timer, SIGNAL(timeout()), this, SLOT(showTime()));
......
}
作为解决方案,我只能建议将连接封装到函数中,并且仅当对象的动态和静态类型相同时才调用该函数。否则,您必须删除该行或拒绝多重继承。
在headers中:
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
......
}
在源文件中:
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()));
......
}
在main.cpp中:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
NewClock c;
c.show();
return a.exec();
}
我想展示NewClock。但是当我编译时,错误是 "cannot convert from pointer to base class 'QObject' to pointer to derived class 'ElecClock' via virtual base 'Clock'."
错误发生在moc_ElecClock.cpp:
void ElecClock::qt_static_metacall(QObject *_o, QMetaObject::Call _c,int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
ElecClock *_t = static_cast<ElecClock *>(_o); // this line
Q_UNUSED(_t)
switch (_id) {
case 0: _t->showTime(); break;
default: ;
}
}
Q_UNUSED(_a);
}
如何解决这个问题?我的构造函数和插槽有什么问题吗? ^
static_cast
这样做:静态转换被称为静态,因为转换所需的计算是在 编译时 完成的,无论是指针算法或转化。
然而,当虚拟继承存在时,事情就变得有点困难了。主要问题是,对于虚拟继承,所有子classes 共享同一个子对象实例。为了做到这一点,ElecClock
将有一个指向 `` 的指针,而不是 Clock
本身,并且 Clock
基础 class 对象将在 ElecClock
.
尽管如此,在编译时不可能推导出必要的指针算法。这取决于对象的运行时类型。
解决方案
您需要 RTTI
(运行时类型信息),使用 RTTI 进行转换是 dynamic_cast
的工作。
安全
static_cast
从基到派生是安全的,只要不变量成立。否则结果为 undefined behavior
。然而,对大型代码库的广泛部分强制执行的不变量很少保持不变。
所以在类似情况下使用static_cast
时,考虑把assert(dynamic_cast<...>(...))
放在前面。
问题来自下面的连接。由于 dynamic_cast
运行速度较慢,因此使用了自动生成的 qt_static_metacall
函数 static_cast
在多重继承的情况下无法转换
ElecClock::ElecClock(QWidget *parent) :
Clock(parent)
{
......
---> connect(timer, SIGNAL(timeout()), this, SLOT(showTime()));
......
}
作为解决方案,我只能建议将连接封装到函数中,并且仅当对象的动态和静态类型相同时才调用该函数。否则,您必须删除该行或拒绝多重继承。