I'm writing classes for widgets on a ui. While planning what I would do, I realized majority of the of the classes would look very similar. What I decided to do was to use a macro that takes a few parameters to define the similar parts of the class bodies. After cleaning a few code errors, I compiled and got a bunch of linker errors. I cleaned and rebuilt a few times with the same result
All of the errors say: error: undefined reference to vtable for 'every class using the macro'. I have an idea the errors are related to using Qt signals and slots with in the macro, but I dont know for sure or how I'd solve the the problem if that is what's causing it.

This is one of the macros that cause some of the errors:

#define GENERAL_GUI_ITEM_CLASSBODY(SIG,EMIT_TYPE)                          \
                                                                                                         \
        Q_OBJECT                                                                         \
                                                                                                                         \
        EMIT_TYPE val;                                                                     \
public:                                                                                                                       \
    inline void connectSIG()                                                                            \
    {                                                                                                                                                    \
        connect(this, SIGNAL(SIG), SLOT(emitRequest()));                                                            \
    }                                                                                                                            \
                                                                                                                           \
    inline void setVal (EMIT_TYPE v) { val = v; }                                          \
                                                                                                                                              \
signals:                                                                                                                         \
    void requested(EMIT_TYPE);                                                                            \
private slots:                                                                                                                              \
    inline void emitRequest() { emit requested (val); }                                      \
    public:

The other macros I'm using have a few more functions all inline and cause the same errors.

Edited 3 Years Ago by James19142

Please show more code. Your error indicates that you are missing some virtual function declarations. The vtable is the virtual function table. Since you aren't showing the derivation of your classes, it is difficult to help further.

this is one of the classes that use the macro

class DamageEnchantButton : public JPushButtonLabel {

    //DamageEnchant is an enum and clicked() is a signal from the inherited class
    //I've use the class being inhereted multiple times as its self without problems, it doesnt have any pure virtual functions
    //but this is my first time deriving from it

    //I started getting errors when I created the classes with bodies defined by this macro and some other marcos similar, they   
    //all cause the same exact error, I figured the problem would spotted easiest within the macro least in size

    GENERAL_GUI_ITEM_CLASSBODY(clicked(),DamageEnchant)

    inline DamageEnchantButton(QWidget *parent ) : JPushButtonLabel (parent) { connectSIG (); }

};

using the macro I'm expecting it to look similar to this (with the exception of the other macros for the signal/slot system) after the preprocessor:

class DamageEnchantButton : public JPushButtonLabel{


     Q_OBJECT        

        DamageEnchant val;                                                   
public:                                                                                                                       
    inline void connectSIG() 
    { connect(this, SIGNAL(clicked()), SLOT(emitRequest())); } 

    inline void setVal (DamageEnchant v) 
    { val = v; }     

signals:                                                                                                                         
    void requested(DamageEnchant); //definition should be compiler generated  

private slots:                                                                                                                              
    inline void emitRequest() { emit requested (val); }    

public:
    inline DamageEnchantButton(QWidget *parent ) : JPushButtonLabel (parent) { connectSIG (); }

};

my bad about the code in the first post, i didnt know having the macro slashes far out would make the code hard to read, wasnt considering the word wrap effect

Edited 3 Years Ago by James19142

I noticed that in the release folder where all the .o and moc prefixed .cpp files are, the moc file for the header containing my macro defined classes is empty. It seems that file is where the funtions declared by the Q_OBJECT macro, and the signal labeled funtions are usually defined by the moc compiler, dont know why its failing to generate the code. As much as I use Qt's signal/slot system, I've never had this problem before.

Edited 3 Years Ago by James19142

I figured out what the problem was. The Q_OBJECT macro was used in the macro I made, as a result the Q_OBJECT functions were declared, but because the Q_OBJECT macro wasn't noticed by the moc compiler, so it didnt create a "moc_" prefixed .cpp file to define the the Q_OBJECT funtions (some were virtual), so they remained undefined. So I can't have that macro placed in another macro if it's gonna be noticed my the moc compiler. Instead of depending on my macro's usage of it, I have to place the Q_OBJECT macro in each class.

Edited 3 Years Ago by James19142

This question has already been answered. Start a new discussion instead.