In class A, I define a class B. I want to hide the implementation of class B. The class B inherits from QObject.
// a.h
class A : public QObject
{
Q_OBJECT
public:
explicit A(QObjcet* parent=nullptr);
private:
class B;
QSharedPointer<B> m_impl;
};
//a.cpp
class A::B : public QObject
{
Q_OBJECT
public:
...
};
A::A(QObject* parent) :
QObject(parent),
m_impl(QSharedPointer<B>(new B()))
{
}
But it has errors:
undefined reference to 'vtable for A::B'
undefined reference to 'A::B::staticMetaObject'
What causes them, and how can I fix them?
For
QObject-derived class to be compiled you need an extra unit containing definitions forQ_OBJECTmacro, generated by meta-object compiler(moc) utility based on conent of the header where class is declared.Nested classes or classes inherited from multiple
QObjects are not supported by Qt and may or may not work. Meta-object compiler also isn't designed to be used on .cpp files because of its limitted ability to parse code. By default Qt toolchains do not runmocon .cpp files.You can create an additional compilation step to run
mocbut that's a dirty and oddball solution, you'd better to have a separate, "private" header if your class is derived fromQObject, hidden in a folder no foreign unit would look up.This looks like B is meant to be a private ("bridged") class used within A:
In that case you must use Qt's PIMPL aka Cheshire cat pattern, which is a variant of Bridge pattern.
How to use the Qt's PIMPL idiom?
TLDR:
A::Bwould become aclass APrivatein global namespace