无法从指针到基类转换为指向派生类的指针

Cannot convert from pointer to base class to pointer to derived class

本文关键字:指针 派生 转换 基类      更新时间:2023-10-16

In 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()));
......
}

在主要.cpp:

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
NewClock c;
c.show();
return a.exec();
}

我想展示新时钟。但是当我编译时,错误是"无法通过虚拟基"时钟"从指针到基类'QObject'转换为指向派生类'ElecClock'的指针。

错误发生在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

这样做:静态强制转换被称为静态,因为转换所需的计算是在编译时完成的,无论是指针算术还是转换。

但是,当虚拟继承存在时,事情变得更加困难。主要问题是,使用虚拟继承时,所有子类都共享子对象的同一实例。为了做到这一点,ElecClock将有一个指向 '' 的指针,而不是一个Clock,并且Clock基类对象将在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())); ...... }

作为解决方案,我只能建议将连接封装到函数中,并且仅在对象的动态和静态类型相同时才调用函数。否则,您必须删除该行或拒绝多重继承。