'QObject' is an ambiguous base of 'Recorder'

isADon picture isADon · Jul 11, 2014 · Viewed 8.1k times · Source

I'm trying to use QTimer, which inherits QObject, in my newly created class. However I try it I keep getting the error 'QObject' is an ambiguous base of 'Recorder' . I did try my best to avoid ambiguity in my simple program but still got stuck with it. Here's the structure of my classes.

#include "dialog.h"
#include <QApplication>

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

    return a.exec();
}

dialog.h: mainwindow UI

#ifndef DIALOG_H
#define DIALOG_H

#include "detector.h"
#include <QDialog>
#include <QtCore>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private:
    Ui::Dialog *ui;
    Detector myDetector;

detector.h: detector window UI

#ifndef DETECTOR_H
#define DETECTOR_H

#include <QDialog>
#include <QtCore>
#include <QObject>
#include "actualrec.h"

namespace Ui {
class Detector;
}

class Detector : public QDialog
{
    Q_OBJECT

public:
    explicit Detector(QWidget *parent = 0);
    ~Detector();
    void run();

private:
    ActualRec theDetector;
    Ui::Detector *ui;

actualrec.h: detector code

#ifndef ACTUALREC_H
#define ACTUALREC_H

#include <QtCore>
#include <QObject>    
#include <QImage>
#include "recorder.h"

class ActualRec : public QThread
{
public:
    ActualRec();
    void run();

private:        
    Recorder theRecorder;

recorder.h: recorder code, where I want to use my QTimer

#ifndef RECORDER_H
#define RECORDER_H

#include <QtCore>

class Recorder : public QThread, public QObject
{

public:
    Recorder();
    void run();

private:
    QTimer* theTimer;

recorder.cpp constructor has

 *theTimer = new QTimer(this);

the output is following: http://i.imgur.com/Awb6qhd.png

Any help would be much appreciated

Answer

lpapp picture lpapp · Jul 11, 2014

You have several issues in your code:

1) Wrong usage of thread with Qt

class Recorder : public QThread, public QObject

a) It is enough to inherit QThread without explicitly inheriting QObject since QThread inherits QObject.

b) Even if you did this, historically, QObject ought to be the first base in the list in a general case.

c) However, you may wish to reconsider how to use your threads. This is one way, but necessarily the best.

2) Allocating an object for QTimer on the heap

Why are you allocating memory on the heap for a timer in the first place? It is OK to allocate it on the stack, especially since it is a member. That way, you would not need to deal with the this hassle either. The whole memory management becomes a lot simpler.

3) Not utilizing Q_NULLPTR

You ought to use it instead of 0 for the default values of the parents.

4) Including the whole QtCore module

#include <QtCore>

You should only include the parts that you eventually use. This is a brute-force way of including things.

Therefore, write something like this instead:

class Recorder : public QThread
{

public:
    Recorder();
    void run();

private:
    QTimer theTimer;

Of course, if you use the threading mechanism the other way around in Qt, then it is perfectly fine to write this instead for the inheritance:

class Recorder : public QObject

but then your code would need some other change, so the code is broken as it is now, either way.