QObject herencia múltiple y operador nuevo

Stuck with this weird question

Why following code is OK for g++

#include <QObject>

class B {
public:
  B(){}
  ~B(){}
};

class A : public QObject, public B {
  Q_OBJECT
public:
  A(QObject * parent = 0 ) : QObject( parent ), B() {}
  ~A(){}
};

int main(int argc, char *argv[])
{
  A a1();
  //A * a = new A();
  //delete a;
  return 0;
}

and this can not be compiled

/*... the same class definitions as above */    

int main(int argc, char *argv[])
{
  //A a1();
  A * a = new A();
  delete a;
  return 0;
}

//error: undefined reference to `vtable for A'

I mean what to do to make the second good as well?

PS Well I put everything in separate files, and it works fine. So it is a matter of Q_OBJECT macros, I think.

preguntado el 10 de marzo de 12 a las 05:03

3 Respuestas

If you define a QObject-derived class, build an application, and realize you forgot to add the Q_OBJECT macro, and you add it later, it is important that you qmake to explicitly update the Makefile. Furthermore, to be safe, I recommend a make clean to get rid of old files. make is not smart enough to clean up all of its generated files under such circumstances, and this is an issue that often causes headaches to new Qt developers.

For more information about this error message, see

http://cartan.cas.suffolk.edu/oopdocbook/html/commonlinkererrors.html#undefinedreftovtable

respondido 10 mar '12, 05:03

Interesting link, thanks. +1. I think it is relevant to the problem. "All-inline Classes For polymorphic classes [72], there should be at least one non-inline definition (a function or a static member) in a source (.cpp) file for that header file. Without this, many linkers will not be able to find any of its virtual method definitions, and will report a similar error. All-inline classes are legal in C++, but they do not work in their intended way when mixed with polymorphism." I think this is perhaps what is going on, as the question-asker mentioned that a .cpp file helped. - tmperace

Thank you, I get rid from my real issue (which I modelling here) from working project when add another class inherited from QObject and rebuild the project. Strange but it helps. - Dmitri Kachko

Why does the First example compile & Link cleanly while Second doesn't?

The first example compiles and links because:
It does not create an object of A,

A a1();

Declara una función a1() which takes no parameter and returns a A tipo.

While the Second example creates an object when new se llama.

Note that the *undefined reference to vtable for A'* is a linking error and will only be emitted when a object ofclass A` is created. Hence only the Second example shows the error.

¿Cómo resolver el problema?
You need to provide definition for all virtual functions which you derive from QObject.

respondido 10 mar '12, 05:03

QObject is not pure virtual; there's nothing you necesitas to provide a definition for. - tmperace

@tmpearce: That is incorrect.You might want to have a look at c++03 10.3 Virtual functions [class.virtual] or este answer of mine. - Guardar

this class compiles OK, no need to implement anything but constructor class C : public QObject { Q_OBJECT public: explicit C(QObject *parent = 0); ~C(){ std::cout << "ok c \n";} int i; signals: public slots: }; - Dmitri Kachko

@Als Perhaps I'm misunderstanding. QObject provides methods for all of its virtual functions. You can override them, but there's nothing that debe: be defined, as a definition already exists. - tmperace

The code works in Vis. Studio. Your problem may be that B is not a polymorphic class - I don't know why that would give you an error - but you could try making something in B virtual: virtual ~B(){} por ejemplo.

respondido 10 mar '12, 05:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.