Undefined reference to vtable for qt ошибка

Автор Тема: Если вылезает ошибка «undefined reference to vtable for …» [СОВЕТ]  (Прочитано 57249 раз)
frostyland

Гость


Если при компиляции появляется ошибка такого рода
undefined reference to vtable for (имя_класса)
то,
1. Вероятно, вы объявили, но забыли реализовать один или несколько виртуальных методов класса, не наследованного от QObject.
2. от пользователя ufna):

хз, на моей практике такая ошибка возникает когда Q_OBJECT забыл добавить, затем вставляешь, но qmake заново не делаешь ))

« Последнее редактирование: Сентябрь 30, 2010, 13:35 от frostyland »
Записан
zenden

Гость


а может просто запустить qmake?? (очень часто указанная ошибка возникает из за отсутствия файла moc)


Записан
frostyland

Гость


а может просто запустить qmake?? (очень часто указанная ошибка возникает из за отсутствия файла moc)

в моем случае не помогло. да и не могло помочь: объявил — реализуй!
просто само сообщение не говорит конкретно в чем ошибка. Поэтому и отписался — чтобы народ не тратил по полчаса-часу, как я )


Записан
navrocky

Гипер активный житель
*****
Offline Offline

Сообщений: 817

Погроммист

Просмотр профиля


То же самое с любым виртуальным методом, который не реализован. Плюс если объявляешь Q_OBJECT но не прогоняешь по нему moc такая же ошибка, частенько встречается когда используется cmake в качестве системы сборки. Или в случае с qmake когда Q_OBJECT объявлен в cpp.


Записан

Гугль в помощь

frostyland

Гость


Блин, ребята.
Ну читайте внимательно, что ли…
Если не реализовал вирт.метод SomeMethod, то компилятор ругается предметно:

undefined reference to ‘SomeMethod’

, и становится ежу понятно, где грабли.

А здесь ругань на vtable для класса, а никак не на

undefined reference to ‘~SomeDestructor’

Мой пост для того, чтобы помочь разобраться в этом, только и делов.


Записан
pastor

Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901

Просмотр профиля
WWW


Блин, ребята.
Ну читайте внимательно, что ли…
Если не реализовал вирт.метод SomeMethod, то компилятор ругается предметно:

Неверно. Как раз будт ошибка линковки:

Undefined reference to ‘vtable for …’


Записан

pastor

Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901

Просмотр профиля
WWW


Для интереса собери код:

C++ (Qt)

class IClass
{
public:
   virtual void foo() = 0;
};

 class MyClass : public IClass
{
public:
   void foo();
};

 MyClass x;

и получишь

Undefined reference to ‘vtable for MyClass’

Деструктор здесь не причем.

« Последнее редактирование: Сентябрь 30, 2010, 12:56 от pastor »
Записан

frostyland

Гость


Уважаемый pastor.
Только что провел еще один тест.
Если класс наследован от QObject, то компилятор в обоих случаях ругается правильно:

В семпле поставляемом с QtCreator 2.0 — browser.pro
Закомментировал mousePressEvent(QMouseEvent*)
Ругается:

undefined reference to `WebView::mousePressEvent(QMouseEvent*)’

Объявил, но не стал реализовывать ~WebView.
Ругнулся правильно

undefined reference to `WebView::~WebView

В моем случае наследование не от QObject:

при нереализованном виртуальном методе

undefined reference [b]to `Vcon::PluginItem::type() const’
[/b]collect2: ld returned 1 exit status

При нереализованном виртуальном деструкторе:

./debugpluginmanager.o: In function `PluginItem’:
V:workQtvconsrcvcon-build-desktop/../vcon/pluginmanager.cpp:358: undefined reference [b]to `vtable for Vcon::PluginItem’ [/b]
V:workQtvconsrcvcon-build-desktop/../vcon/pluginmanager.cpp:358: undefined reference [b]to `vtable for Vcon::PluginItem’ [/b]
collect2: ld returned 1 exit status

Для чистоты эксперимента в вышеназванном проекте browser сделал виртуальным деструктор ~BookmarkNode();
До виртуализации при отсутствии реализации компилятор правильно ругался на

C:Qt2010.04qtdemosbrowser-build-desktop/../browser/bookmarks.cpp:299: undefined reference [b]to `BookmarkNode::~BookmarkNode()'[/b]

а с виртуализацией

C:Qt2010.04qtdemosbrowser-build-desktop/../browser/xbel.cpp:49: undefined reference [b]to `vtable for BookmarkNode’ [/b]


Записан
frostyland

Гость


Ну да. При сборке IClass все как Вы сказали.
Надо резюмировать как-то )
Например, ошибка с vtable может возникнуть в случае отсутствия реализации части виртуальных методов. Как-то так?


Записан
ufna

Гость


хз, на моей практике такая ошибка возникает когда Q_OBJECT забыл добавить, затем вставляешь, но qmake заново не делаешь ))


Записан
pastor

Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901

Просмотр профиля
WWW


Теперь берем тотже пример и делаем вызов foo():

C++ (Qt)

class IClass
{
public:
   virtual void foo() = 0;
};

 class MyClass : public IClass
{
public:
   void foo();
};

 MyClass x;
x.foo();

Смотрм, что получилось Улыбающийся

Думаю сейчас все станет ясно


Записан

kdm

Гость


Очень дельный совет, у меня такое часто когда-то случалось. В такие моменты я вообще был в растерянности и пересоздавал набор файлов класса *.cpp, *.h.

« Последнее редактирование: Октябрь 02, 2010, 18:41 от kdm »
Записан
frostyland

Гость


Теперь берем тотже пример и делаем вызов foo():

Думаю сейчас все станет ясно

Да, я примерил пример, и поправил первое сообщение. Вполне возможно, кому-то будет полезно.


Записан
blood_shadow

Гость


То же самое с любым виртуальным методом, который не реализован. Плюс если объявляешь Q_OBJECT но не прогоняешь по нему moc такая же ошибка, частенько встречается когда используется cmake в качестве системы сборки. Или в случае с qmake когда Q_OBJECT объявлен в cpp.

у меня с qmake такое получилось(программа состоит с одного файла .срр) закоментил Q_OBJECT в файле cpp и все стало норм. Кто знает из-за чего это? Баг линкера?
и еще как тогда реализовать сигналы и слоты если приходиться выбрасывать макрос Q_OBJECT() ?
вот код к примеру:

#include <iostream>
#include <QMainWindow>
#include <QtGui/QApplication>
#include <QObject>

using std::cout;
using std::endl;

class Test : public QMainWindow
{
    //Q_OBJECT;

public:
    Test(QWidget *parent = 0) : QMainWindow(parent) {}
    void Click() { setWindowFilePath(«file.txt»); }
    ~Test() {}

};

int main(int argc, char *argv[])
{

    QApplication app(argc, argv);

    Test test;
    test.show();

    return app.exec();

}


Записан
alexman

Гость


; попробуй убрать!


Записан

I’ve seen a lot of ways to solve the problem, but no explanation for why it happens, so here goes.

When the compiler sees a class with virtual functions (directly declared or inherited), it must generate a vtable for that class. Since classes are generally defined in headers (and thus appear in multiple translation units), the question is where to place the vtable.

In general, the problem can be solved by generating the vtable in every TU* where the class is defined, and then let the linker eliminate duplicates. Since class definitions are required to be the same on every occurrence by the ODR**, this is safe. However, it also slows down compilation, bloats object files, and requires the linker to do more work.

As an optimization, therefore, compilers will, when possible, choose a specific TU to put the vtable in. In the common C++ ABI***, this TU is the one where the key function of the class is implemented in, where the key function is the first virtual member function that is declared in the class, but not defined.

In the case of Qt classes, they usually start with the Q_OBJECT macro, and this macro contains the declaration

virtual const QMetaObject *metaObject() const;

which, since it is the first virtual function in the macro, will generally be the first virtual function of the class and thus its key function. The compiler will therefore not emit the vtable in most TUs, only the one that implements metaObject. And this function’s implementation is written automatically by moc when it processes the header. Thus, you need to have moc process your header to generate a new .cpp file, and then include the .cpp file in your compilation.

So when you have a new header that defines a QObject-derived class, you need to rerun qmake so that it updates your makefiles to run moc on the new header and compile the resulting .cpp file.

* TU: Translation Unit. A term of art in C and C++, it refers to a single source file plus all the header files transitively included from it. Basically, the stuff the compiler sees when it works on a single source file.

** ODR: One Definition Rule. A set of rules in the C++ standard that define what happens when things (functions, classes, etc.) are defined multiple times in different translation units.

*** ABI: Application Binary Interface. A description of the way the code is organized when compiled, necessary for object files to be linked together. The Common C++ ABI is a specification that compilers for Linux generally follow so that they can interoperate.

Есть пример кода из книги Шлее о Qt 5.3. Он разбросан на хедер Progress.h, где лежит определение класса Progress, Progress.cpp, где лежат определения методов этого класса, и основной файл main.cpp. Я закинул все в один файл main.cpp.

// Как бы файл Progress.h
#include <QApplication>
#include <QtWidgets>
#include <QProgressBar>
#include <QPushButton>

// ======================================================================
class Progress : public QWidget {
    Q_OBJECT
private:
    QProgressBar* m_pprb;
    int           m_nStep;

public:
    Progress(QWidget* pobj = 0);

public slots:
    void slotStep ();
    void slotReset();
};

// ----------------------------------------------------------------------
Progress::Progress(QWidget* pwgt/*= 0*/)
    : QWidget(pwgt)
    , m_nStep(0)
{
    m_pprb = new QProgressBar;
    m_pprb->setRange(0, 5);
    m_pprb->setMinimumWidth(200);
    m_pprb->setAlignment(Qt::AlignCenter);

    QPushButton* pcmdStep  = new QPushButton("&Step");
    QPushButton* pcmdReset = new QPushButton("&Reset");

    QObject::connect(pcmdStep, SIGNAL(clicked()), SLOT(slotStep()));
    QObject::connect(pcmdReset, SIGNAL(clicked()), SLOT(slotReset()));

    //Layout setup
    QHBoxLayout* phbxLayout = new QHBoxLayout;
    phbxLayout->addWidget(m_pprb);
    phbxLayout->addWidget(pcmdStep);
    phbxLayout->addWidget(pcmdReset);
    setLayout(phbxLayout);
}
// Как бы файл Progress.cpp
// ----------------------------------------------------------------------
void Progress::slotStep()
{
    m_pprb->setValue(++m_nStep);
}

// ----------------------------------------------------------------------
void Progress::slotReset()
{
    m_nStep = 0;
    m_pprb->reset();
}
// Как бы файл main()
// ----------------------------------------------------------------------
int main (int argc, char** argv)
{
    QApplication app(argc, argv);
    Progress     progress;

    progress.show();

    return app.exec();
}

В этом случае файл не компилируется, вылетают ошибки:

main.o: In function `Progress::Progress(QWidget*)':
/mnt/data-disk/MEGA/Programming/C++/build-untitled1-Desktop-Debug/../untitled1/main.cpp:24: undefined reference to `vtable for Progress'
/mnt/data-disk/MEGA/Programming/C++/build-untitled1-Desktop-Debug/../untitled1/main.cpp:24: undefined reference to `vtable for Progress'
main.o: In function `Progress::~Progress()':
/mnt/data-disk/MEGA/Programming/C++/build-untitled1-Desktop-Debug/../untitled1/main.cpp:7: undefined reference to `vtable for Progress'
/mnt/data-disk/MEGA/Programming/C++/build-untitled1-Desktop-Debug/../untitled1/main.cpp:7: undefined reference to `vtable for Progress'

Подскажите пожалуйста, почему так?

Hi everybody, I got a big problem … I want to connect a PushButton with a slot to save some parameters but I have an error when I make the project…

So my H file is :
@#ifndef CONFIGRS232_H
#define CONFIGRS232_H

#include <QtGui>
#include <QWidget>

class ConfigRS232: public QWidget
{
Q_OBJECT

QPushButton *saveConfigButton;

public:
ConfigRS232(QWidget *parent = 0);

private:
int _portCom;
int _baudRate;
int _dataLength;
int _parity;
int _stopBit;

QComboBox *portCom;
QComboBox *baudRate;
QComboBox *dataLength;
QComboBox *parity;
QComboBox *stopBit;

public slots:
void SaveConfigParameters();
};

#endif // CONFIGRS232_H@

And my .cpp file is
@#include «configrs232.h»

#include <iostream>
using namespace std;

ConfigRS232::ConfigRS232(QWidget *parent)
: QWidget(parent)
{
QGroupBox *rs232ConfigGroup = new QGroupBox(tr(«RS232 Configuration»));

QLabel *pComLabel = new QLabel(tr("Com Port #"));
portCom = new QComboBox;
QLabel *pBaudLabel = new QLabel(tr("Bite Rate (bps):"));
baudRate = new QComboBox;
QLabel *pDataLabel = new QLabel(tr("Data Length:"));
dataLength = new QComboBox;
QLabel *pParLabel = new QLabel(tr("Parity:"));
parity = new QComboBox;
QLabel *pStopLabel = new QLabel(tr("Stop Bit:"));
stopBit = new QComboBox;

portCom->addItem("1",1);
portCom->addItem("2",2);
portCom->addItem("3",3);
portCom->addItem("4",4);
portCom->addItem("5",5);
portCom->addItem("6",6);
portCom->addItem("7",7);
portCom->addItem("8",8);

baudRate->addItem("4800",4800);
baudRate->addItem("9600",9600);
baudRate->addItem("19200",19200);
baudRate->addItem("38400",38400);
baudRate->addItem("57600",57600);

dataLength->addItem("5",5);
dataLength->addItem("6",6);
dataLength->addItem("7",7);
dataLength->addItem("8",8);

parity->addItem("None","None");
parity->addItem("Even","Even");
parity->addItem("Odd","Odd");

stopBit->addItem("1",1);
stopBit->addItem("2",2);

saveConfigButton = new QPushButton(tr("Save Configuration"));

QGridLayout *updateLayout = new QGridLayout;
updateLayout->addWidget(pComLabel,0,0);
updateLayout->addWidget(portCom,0,1);
updateLayout->addWidget(pBaudLabel,1,0);
updateLayout->addWidget(baudRate,1,1);
updateLayout->addWidget(pDataLabel,2,0);
updateLayout->addWidget(dataLength,2,1);
updateLayout->addWidget(pParLabel,3,0);
updateLayout->addWidget(parity,3,1);
updateLayout->addWidget(pStopLabel,4,0);
updateLayout->addWidget(stopBit,4,1);
rs232ConfigGroup->setLayout(updateLayout);

QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(rs232ConfigGroup);
mainLayout->addWidget(rs232ConfigGroup);
mainLayout->addSpacing(12);
mainLayout->addWidget(saveConfigButton);
mainLayout->addStretch(1);
setLayout(mainLayout);

connect(saveConfigButton, SIGNAL(clicked()), this, SLOT(SaveConfigParameters())); // here is my problem

}

void ConfigRS232::SaveConfigParameters()
{
_portCom = portCom->currentIndex();
_baudRate = baudRate->currentIndex();
_dataLength = dataLength->currentIndex();
_parity = parity->currentIndex();
_stopBit = stopBit->currentIndex();

cout << endl << "Port Com # : " << _portCom << endl;

}@

Just for more precisions, I tried without instanciate Q_OBJECT in the .h file but it doesn’t connect my pushbutton with my slot (SaveConfigParameters) …

Somebody have an idea ?

Библиотеки Qt комплектуются программой qmake, которая выполняет все необходимые подготовительные действия, чтобы компиллятор смог нормально собрать проект, в том же MinGW и nmake нет поддрежки ни signals ни slots, однако компиллят.

В общем при возникновении проблемы с vtable чаще всего помогает «Сборка — Очистить все», «Сборка — Запустить qmake»
Ну и дальше уже собирать проект
moc-файл вручную не сделать, точнее можно, но тогда надо внутренности Qt знать от и до, АБСОЛЮТНО

Добавлено через 55 секунд
То что разбиение помогло — это из-за того, что изменилась конфигурация проекта и qmake был вызван автоматически

The undefined reference to vtable for constructor code exception obliterates your programming experience when the cpp file is not in the main makefile. In addition, your program will likely experience this linker error log when one of your classes derives definitions from other classes with inadequate values and properties. Finally, the system can display the undefined reference to vtable cmake bug when one or more classes get broken reports and types.Undefined Reference to Vtable

Taking that into consideration, we wrote the ultimate debugging article to help you overcome the undefined reference using real-life examples and scripts that do not affect other functions and commands.

Contents

  • When Does the Undefined Reference to Vtable Code Exception Happen?
    • – Due to a Broken Constructor
    • – Failing To Define Destructors on an Interface Project
  • How To Fix the Undefined Reference to Vtable Code Exception?
    • – Changing the Destructors and the Account Database
  • Conclusion

When Does the Undefined Reference to Vtable Code Exception Happen?

The undefined reference to vtable for destructor error log happens when the cpp file is not in the primary makefile. Moreover, this mistake can obliterate your programming experience when one of your app’s classes derives definitions from other classes with inadequate values. These culprits raise identical warnings and invalid messages.

Therefore, this undefined reference to vtable for qobject is almost inevitable when your project’s main makefile misses some files and scripts. In addition, although this mistake is typical with complex applications and programs, it can affect any project regardless of elements, functions, and commands.

Therefore, we will help you remake the undefined reference to vtable for base class bug using several syntaxes launching basic properties, which should help you understand the error’s exact cause.

You should not worry if the functions in your document differ because the debugging techniques and bug’s root remain identical for all operating systems and applications.

On the flip side, the undefined reference to `typeinfo for mistake is inevitable when the classes in your script derive other classes with broken values or inputs. Although this sounds harmless, calling classes improperly can severely affect your programming experience or project, especially with advanced properties and inputs.

Moreover, we confirmed the undefined reference to vtable for enemy instance when your elements create a vtable reference for the iBase where the document cannot find any compiled objects of iBase to look up. So, the vtable symbol may be undefined because the class is missing its key function, which is a vital indicator when applying the solutions.

– Due to a Broken Constructor

This article’s first broken instance creates a basic application with a broken constructor, which launches the error log and terminates the program.

As a result, we will show you the related source code and the code snippet that inherits the constructors. Although these syntaxes only include several elements and commands, your system fails to render the values and displays a warning.Undefined Reference to Vtable Causes

The following example provides the basic source code:

class CGameModule : public CDasherModule {

public:

CGameModules (Dasher:: CEventHandler *pEventHandler, CSettingsStores *pSettingsStores, CDasherInterfaceBase *pInterface, ModuleID_t iIDs, const char *szName)

: CDasherModule (pEventHandler, pSettingsStore, iID, 0, szName)

{

g_pLogger -> Log (“Inside game module constructor”);

m_pInterface = pInterface;

}

virtual ~CGameModule() {};

std:: string GetTypedTarget();

std:: string GetUntypedTarget();

bool DecorateView (CDasherView *pView) {

//g_pLogger -> Log (“Decorating the view”);

return false;

}

void SetDasherModel (CDasherModel *pModel) { m_pModel = pModel; }

virtual void HandleEvent (Dasher:: CEvent *pEvent);

private:

CDasherNode *pLastTypedNode;

CDasherNode *pNextTargetNode;

std:: string m_sTargetString;

size_t m_stCurrentStringPos;

CDasherModel *m_pModel;

CDasherInterfaceBase *m_pInterface;

};

After providing the inherited code snippet, we can only finish recreating the code exception. We must note that each document is unique and launches different values, so your project likely has other inputs that keep the solutions the same.

You can learn about the inherited code snippet below:

class CDasherModules;

typedef std::vector <CDasherModule*> ::size_type ModuleID_t;

/// ingroup Core

/// @{

class CDasherModules : public Dasher:: CDasherComponent {

public:

CDasherModules (Dasher:: CEventHandler * pEventHandler, CSettingsStores * pSettingsStores, ModuleID_t iID, int iType, const char *szName);

virtual ModuleID_t GetID();

virtual void SetIDs(ModuleID_t);

virtual int GetType();

virtual const char *GetNames();

virtual bool GetSettings (SModuleSettings **pSettings, int *iCount) {

return false;

};

private:

ModuleID_t m_iID;

int m_iTypes;

const char *m_szName;

};

This section completes the first broken instance, but it is one of many such cases.

– Failing To Define Destructors on an Interface Project

Your system encounters a similar undefined reference exception when failing to define destructors on an interface project. As a result, the machine displays a warning confirming the inconsistencies and halting further procedures.

We will provide you with the script causing this error log that renders several destructors with straightforward values and inputs.

You can learn more about this code snippet in the following example:

#include <cstdio>

#include <map>

struct Logger {

virtual ~Logger() = default;

virtual void log_transfer(long from, long to, double amount) = 0;

};

struct AccountDatabase {

virtual ~AccountDatabase() = default;

virtual void retrieve_amount(long id);

virtual void set_amount(long id, double amount);

};

struct ConsoleLogger : Logger {

void log_transfer(long from, long to, double amount) override {

printf(“[cons] %1d -> %1d: %fn”, from, to, amount);

}

};

struct FileLogger : Logger {

void log_transfer(long from, long to, double amount) override {

printf(“[file] %1d, %1d, %fn”, from, to, amount);

}

};

struct InMemoryAccountDatabase : AccountDatabase {

void retrieve_amount(long id) override {

printf(“Account Balance: %fn”, m[id]);

}

void set_amount(long id, double amount) override {

m[id] = amount;

printf(“Set Account: %1d, to Balance: %fn”, id, amount);

}

private:

std::map<long, double> m;

};

struct Bank {

void set_logger(Logger* new_logger) {

logger = new_logger;

}

void make_transfer(long from, long to, double amount) {

if (logger) logger->log_transfer(from, to, amount);

}

private:

Logger *logger{};

};

int main() {

InMemoryAccountDatabase db;

db.set_amount(0, 2000);

db.retrieve_amount(0);

}

Although we could include other elements and commands, we kept the example as short as possible. You can use this code snippet to pinpoint the failed commands.

How To Fix the Undefined Reference to Vtable Code Exception?

You can fix the vtable undefined reference code exception by modifying the classes if the snippet misses a function you indicated in the definition. In addition, you must repeat this debugging approach for all virtual and non-virtual functions to repair the program and prevent further complications.



This section confirms overcoming the broken exception is relatively straightforward after changing the classes and their values. In addition, this approach works for all projects and applications because the responsible type is identical.

Next, check the link command carrying the object file with the function’s definition to clarify the inconsistencies. Finally, we will summarize the debugging technique in a few standard steps.

The following numbered list explains the first approach:

  1. Troubleshoot and look at the broken class definition. Locate the primary non-inline virtual function whose definitions you provided in the properties.
  2. You must modify the class to create one if no such function exists.
  3. Find an adequate definition for the mentioned function. Create a new definition if it is missing from the class.
  4. Ensure the function definition has a qualified name if the definition is outside the class. The following code line exemplifies the class name: ClassName:: function_name.
  5. Check the link command. Fix the function’s definition if the script does not mention the object file.
  6. Repeat the preliminary steps for each virtual and non-virtual function until the system removes the mistake. Repeat the debugging approach for all static data members if the error log persists.

Your program should no longer experience this code exception after fixing the function definitions and non-virtual functions.

– Changing the Destructors and the Account Database

Another excellent debugging approach suggests changing the destructors and the account database to overcome the mistake. As a result, you will clear the inconsistencies and repair the virtual values confusing your program and displaying the error log.Changing the Destructors and the Account Database

Although the destructors and account database values are unique for each document, the technique repairs all code snippets regardless of purpose. We will exemplify the code differences by listing the incorrect and fixed syntaxes to help you understand the changes.

The following example provides the broken destructors:

struct AccountDatabase {

virtual ~AccountDatabase() = default;

virtual void retrieve_amount (long id);

virtual void set_amount (long id, double amount);

};

Although this example appears functional without apparent obstacles, your system throws a warning confirming the undefined reference. Hence, we suggest placing curly braces after the voids to indicate the purpose and fix the issue. Still, remember to add an opening and a closing brace after each command.

You can learn about the changed inputs in the following example:

struct AccountDatabase {

virtual ~AccountDatabase() = default;

virtual void retrieve_amount (long id) {}

virtual void set_amount (long id, double amount) {}

};

This section confirms overcoming the undefined reference bug is simple after adding the necessary inputs and properties. The code alteration seems insignificant, but it significantly affects your code.

Conclusion

The undefined reference to vtable code exception obliterates your programming experience when the cpp file is not in the main makefile. However, we fixed the issue, so let’s remember the vital points:

  • The bug happens when one of your app’s classes derives definitions from other classes with inadequate values
  • We reproduced the mistake when failing to define destructors on an interface project
  • The first debugging approach suggests modifying the classes if the snippet misses a function you indicated in the definition
  • You can fix the system by adding curly braces after the voids

Your application or project should be error-free after implementing the solutions and techniques shared in this article. We encourage you to open and repair your project because the keys are accessible.

  • Author
  • Recent Posts

Position is Everything

Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL. Meet The Team

Position is Everything

September 19 2013, 21:02

Category:

  • IT
  • Cancel

Тысячу и один раз это отвечено на stackoverflow, и в тысячу и один раз начинается тупак под вечер, когда не удается вспомнить все возможные причины. Итак, причины error: undefined reference to `vtable и пути их решения:

  1. Класс унаследовал чистые виртуальные функции и не переопределил их. Определите их.
  2. Класс был объявлен наследником QObject с макросом Q_OBJECT после moc-а. Сделайте moc заново.
  3. Заголовочный файл не включен в проект или был включен до появления в нём Q_OBJECT-а. Пересоберите проект, либо (короткий путь) обновите таймштамп файла проекта и сделайте Build.
    Например, быстрый способ обновить таймштампы всех подпроектов:
    # find . -name '*.pro' -exec touch '{}' ;
  4. Макрос Q_OBJECT используется не в заголовочном файле. Нужно добавить #include "<BASENAME>.moc" в исходник, это укажет qmake-у выполнить moc для этого файла, чтобы сгенерировать код для QObject-а (сигналы/слоты и т.д.). Поместить #include «<BASENAME>.moc» нужно просто в конце файла <BASENAME>.cpp и затем пересобрать проект.
    За этот пункт спасибо ответу в вопросе http://stackoverflow.com/questions/21729769/why-is-vtable-linking-issue-while-adding-javascript-window-object.

И отдыхайте чаще. Во всех случаях.

  • Home
  • Forum
  • Qt
  • Qt Programming
  • [SOLVED] Qt: Signals and slots Error: undefined reference to `vtable for

  1. Unhappy [SOLVED] Qt: Signals and slots Error: undefined reference to `vtable for

    Following example from this link: http://developer.kde.org/documentati…3lev1sec3.html

    1. #include <QObject>

    2. #include <QPushButton>

    3. #include <iostream>

    4. using namespace std;

    5. class MyWindow : public QWidget

    6. {

    7. Q_OBJECT // Enable slots and signals

    8. public:

    9. MyWindow();

    10. private slots:

    11. void slotButton1();

    12. void slotButton2();

    13. void slotButtons();

    14. private:

    15. };

    16. MyWindow :: MyWindow() : QWidget()

    17. {

    18. // Create button1 and connect button1->clicked() to this->slotButton1()

    19. button1->setGeometry(10,10,100,40);

    20. button1->show();

    21. connect(button1, SIGNAL(clicked()), this, SLOT(slotButton1()));

    22. // Create button2 and connect button2->clicked() to this->slotButton2()

    23. button2->setGeometry(110,10,100,40);

    24. button2->show();

    25. connect(button2, SIGNAL(clicked()), this, SLOT(slotButton2()));

    26. // When any button is clicked, call this->slotButtons()

    27. connect(button1, SIGNAL(clicked()), this, SLOT(slotButtons()));

    28. connect(button2, SIGNAL(clicked()), this, SLOT(slotButtons()));

    29. }

    30. // This slot is called when button1 is clicked.

    31. void MyWindow::slotButton1()

    32. {

    33. cout << "Button1 was clicked" << endl;

    34. }

    35. // This slot is called when button2 is clicked

    36. void MyWindow::slotButton2()

    37. {

    38. cout << "Button2 was clicked" << endl;

    39. }

    40. // This slot is called when any of the buttons were clicked

    41. void MyWindow::slotButtons()

    42. {

    43. cout << "A button was clicked" << endl;

    44. }

    45. int main ()

    46. {

    47. MyWindow a;

    48. }

    To copy to clipboard, switch view to plain text mode 

    results in:

    1. [13:33:45 Mon May 02] ~/junkPrograms/src/nonsense $ls

    2. nonsense.pro signalsSlots.cpp

    3. [13:33:46 Mon May 02] ~/junkPrograms/src/nonsense $qmake

    4. [13:33:50 Mon May 02] ~/junkPrograms/src/nonsense $make

    5. g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.05/qt/mkspecs/linux-g++-64 -I. -I/opt/qtsdk-2010.05/qt/include/QtCore -I/opt/qtsdk-2010.05/qt/include/QtGui -I/opt/qtsdk-2010.05/qt/include -I. -I. -o signalsSlots.o signalsSlots.cpp

    6. g++ -m64 -Wl,-O1 -Wl,-rpath,/opt/qtsdk-2010.05/qt/lib -o nonsense signalsSlots.o -L/opt/qtsdk-2010.05/qt/lib -lQtGui -L/opt/qtsdk-2010.05/qt/lib -L/usr/X11R6/lib64 -lQtCore -lpthread

    7. signalsSlots.o: In function `MyWindow::MyWindow()':

    8. signalsSlots.cpp:(.text+0x1a2): undefined reference to `vtable for MyWindow'

    9. signalsSlots.cpp:(.text+0x1aa): undefined reference to `vtable for MyWindow'

    10. signalsSlots.o: In function `MyWindow::MyWindow()':

    11. signalsSlots.cpp:(.text+0x3e2): undefined reference to `vtable for MyWindow'

    12. signalsSlots.cpp:(.text+0x3ea): undefined reference to `vtable for MyWindow'

    13. signalsSlots.o: In function `main':

    14. signalsSlots.cpp:(.text+0x614): undefined reference to `vtable for MyWindow'

    15. signalsSlots.o:signalsSlots.cpp:(.text+0x61d): more undefined references to `vtable for MyWindow' follow

    16. collect2: ld returned 1 exit status

    17. make: *** [nonsense] Error 1

    To copy to clipboard, switch view to plain text mode 

    What’s the reason of error here? I did a make clean and then make, it hasn’t helped!

    Last edited by TheIndependentAquarius; 2nd May 2011 at 09:42.


  2. Default Re: Qt: Signals and slots Error: undefined reference to `vtable for

    The output above clearly shows that there’s no moc file generated.

    This probably means that you are using an old makefile.
    Remove all generated files before rebuilding again. It might be interesting to separate build and source directories. This way you can just delete the build directory and rebuild again.


  3. The following user says thank you to tbscope for this useful post:


  4. Default Re: Qt: Signals and slots Error: undefined reference to `vtable for

    thanks for responding, it is solved, some «moc» files hadn’t generated because I didn’t separate the code for the header, source and the main.cpp! and I couldn’t find any error message related to the «moc» file in the above list of errors.

    and I mentioned before that I did a make clean, make distclean, but nothing helped.


  5. Default Re: Qt: Signals and slots Error: undefined reference to `vtable for

    Running make clean or make distclean is nothing to do with re-freshing an old makefile. For that you need to run qmake.

    Also, you don’t have to seperate the code from the header as long as you inform qmake that you have done so by adding the line ‘#include «filename.moc»‘ to the end of your source file.


  6. The following user says thank you to squidge for this useful post:


  7. Default Re: Qt: Signals and slots Error: undefined reference to `vtable for

    Thanks, I’ll try that in my next example.


Similar Threads

  1. Replies: 5

    Last Post: 10th March 2011, 01:38

  2. Replies: 4

    Last Post: 17th October 2008, 15:59

  3. Replies: 5

    Last Post: 7th November 2007, 14:46

  4. Replies: 23

    Last Post: 15th June 2007, 11:21

  5. Replies: 5

    Last Post: 14th February 2006, 23:43

Bookmarks

Bookmarks


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
  • BB code is On
  • Smilies are On
  • [IMG] code is On
  • [VIDEO] code is On
  • HTML code is Off

Forum Rules

Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.

Понравилась статья? Поделить с друзьями:
  • Undefined instagram ошибка
  • Undefined index php ошибка что значит
  • Undeclared first use in this function ошибка c
  • Und ошибка на машинке haier
  • Unconnected line altium ошибка