8

I know the question have been asked tons of times but I can't find the solution here nor in google.

Here's my header file

#ifndef MAINCONTROLLER_H
#define MAINCONTROLLER_H

#include <QSettings>
#include <QDebug>
#include <QDir>
#include <QObject>

#include "PhTools/PhString.h"
#include "PhStrip/PhStripDoc.h"

class MainController : public QObject
{
    Q_OBJECT

public:
    explicit MainController(QObject *parent = 0);
    void loadSettings();
    PhString getLastFile();
    void setLastFile(PhString fileName);
    bool openDoc(PhString fileName);

signals:
    void docChanged();

private:
    QSettings * _settings;
    PhStripDoc * _doc;

};

#endif // MAINCONTROLLER_H

And my CPP file :

#include "MainController.h"


MainController::MainController(QObject *parent) :
    QObject(parent)
{
    _doc = new PhStripDoc();
    loadSettings();
}
void MainController::loadSettings()
{
    _settings = new QSettings(QDir::homePath() + "/Library/Preferences/com.me.me.plist", QSettings::NativeFormat);

    getLastFile();
}

PhString MainController::getLastFile()
{
    qDebug() << "lastfile :" << _settings->value("last_file", "").toString();
    return _settings->value("last_file").toString();
}

bool MainController::openDoc(PhString fileName)
{
    bool succeed = _doc->openDX(fileName);
    if (succeed)
        emit docChanged();
    return succeed;
}

void MainController::setLastFile(PhString filename)
{
    _settings->setValue("last_file", filename);
}

And here's the error log :

Undefined symbols for architecture x86_64:
  "MainController::docChanged()", referenced from:
      MainController::openDoc(QString) in MainController.o
  "vtable for MainController", referenced from:
      MainController::MainController(QObject*) in MainController.o
      MainController::MainController(QObject*) in MainController.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

It might come from signals but I'm not sure...

László Papp
  • 51,870
  • 39
  • 111
  • 135
Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
  • possible duplicate of [Class with virtual function, when derived from QObject, leads to linking error](http://stackoverflow.com/questions/7103964/class-with-virtual-function-when-derived-from-qobject-leads-to-linking-error) – Mats Petersson Jul 02 '13 at 15:16
  • (There are several others duplicates) – Mats Petersson Jul 02 '13 at 15:16
  • @MatsPetersson : Nice. The _"solution"_ you linked with solve **nothing** for me. But thank you anyway, now I'm stuck. Furthermore, I **need** QObject to use signals. – Thomas Ayoub Jul 02 '13 at 15:20
  • In a comment to this answer, it says that editing the `.pro` file helped solve the problem (and running qmake): http://stackoverflow.com/questions/4774291/q-object-throwing-undefined-reference-to-vtable-error – Mats Petersson Jul 02 '13 at 15:42
  • unfortunately my `.pro` fil is already with `Qt += gui` and running qmake don't change – Thomas Ayoub Jul 02 '13 at 19:36
  • Is it possible that the `docChanged` error is causing the type to be incomplete -> no class generated -> no vtable? – Mats Petersson Jul 02 '13 at 21:22
  • @MatsPetersson : `docChanged()` is a signal and have no implementation, this kind of structure is already working on other projects I'm working with and that's why I don't understand the issue – Thomas Ayoub Jul 03 '13 at 06:46
  • Surely the compiler shouldn't complain about it tho'. So somethijng is wrong there too. – Mats Petersson Jul 03 '13 at 07:26
  • @MatsPetersson I solved it with the MOC solution, I might was a little tired yesterday. Thank you! (http://stackoverflow.com/a/4774338/2307070) – Thomas Ayoub Jul 03 '13 at 07:38
  • As said in the last comment, I've solved it but not with you method, that's why I can't accept yours... – Thomas Ayoub Sep 28 '13 at 08:14

2 Answers2

14

When the Q_OBJECT macro is added after the code has already been compiled, qmake has to be run again. This will add the creation and compilation of MainController.moc to your Makefile thus preventing the linker error.

Sebastian
  • 181
  • 1
  • 4
  • 3
    Thanks! This fixed my problem after I added the `Q_OBJECT` macro. Right click your project and click **Run qmake** then try building again. – mattbell87 Feb 19 '16 at 04:15
2

You need to include this line at the end of your source file:

#include "MainController.moc"

Alternatively, you can also handle this with your buildsystem, but that is probably the former is easier.

László Papp
  • 51,870
  • 39
  • 111
  • 135