Search code examples
c++qtsignals-slots

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


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
......
}

In source files:

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

In main.cpp:

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

    return a.exec();
}

I want to show the NewClock. But when i compile, the error is "cannot convert from pointer to base class 'QObject' to pointer to derived class 'ElecClock' via virtual base 'Clock'."

The error happens in 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);
}

How to solve this problem? Is there anything wrong in my constructors and slots? ^


Solution

  • The problem comes from connection below. As dynamic_cast is working slower the automatically generated qt_static_metacall function used static_cast which is not able to cast in case of multiple inheritance

    ElecClock::ElecClock(QWidget *parent) : Clock(parent) { ...... ---> connect(timer, SIGNAL(timeout()), this, SLOT(showTime())); ...... }

    As solution I just can advice to encapsulate connection into function and call the function only if dynamic and static types of object are same. Otherwise you have to remove that line or refuse from multiple inheritance.