开发者

VTable Not Generated

First of all, thank you very much for taking the time to look at my question. Second, I have read this and my class does not have any virtual methods I am forgetting to include. I'll go over additional things I have tried after I describe my problem.

I am getting an undefined reference to `vtable for SubcomponentTypeWidget' error when I build my code using gcc version 3.4.6 20060404. Visual Studio 2005 has no issues. I love Linux, but my current political situation has delegated it to the red headed step child that regularly suffers abuse. Hopefully by our powers combined, I can remedy that.

I am using Qt version 4.6.2. I am using gcc 3.4.6 20060404 on Red Hat 4.

This is my header:

#ifndef SubcomponentTypeWidget_h
#define SubcomponentTypeWidget_h

#include <vector>
#include "ui_SubcomponentTypeWidget.h"
#include "Subcomponent.h"

class SubcomponentTypeWidget : public QWidget, public Ui::SubcomponentTypeWidget
{
    Q_OBJECT

    Q_PROPERTY(QString title READ title WRITE setTitle)

public:
    SubcomponentTypeWidget(QWidget* parent,
        Models::Subcomponent::SubcomponentType subcomponentType = Models::Subcomponent::kSolid)
    :   QWidget(parent),
    m_subcomponentType(subcomponentType),
        m_subcomponentTypeButtonGroup(new QButtonGroup(this))
    {
        this->initialize();
    }

    Models::Subcomponent::SubcomponentType subcomponentType() const { return m_subcomponentType; }

    void setSubcomponentType(Models::Subcomponent::SubcomponentType type);
    void setNonCompatibleTypes(const std::vector<Models::Subcomponent::SubcomponentType>& types);

    QString title() const { return m_subcomponentGroupBox->title(); }
    void setTitle(const QString &title) { m_subcomponentGroupBox->setTitle(title); }

signals:
    void subcomponentTypeChanged();

pr开发者_StackOverflow中文版otected slots:
    void handleSubcomponentTypeChoice(int subcomponentTypeChoiceId);

protected:
    void initialize();
    Models::Subcomponent::SubcomponentType m_subcomponentType;
    QButtonGroup* m_subcomponentTypeButtonGroup;
};

#endif // SubcomponentTypeWidget_h

The implementation is here:

#include "SubcomponentTypeWidget.h"

void SubcomponentTypeWidget::setSubcomponentType(Models::Subcomponent::SubcomponentType type)
{
    if (type != m_subcomponentType)
    {
        m_subcomponentType = type;
        emit subcomponentTypeChanged();
    }
}

void SubcomponentTypeWidget::setNonCompatibleTypes(const std::vector<Models::Subcomponent::SubcomponentType>& types)
{
    m_subcomponentTypeButtonGroup->button(static_cast<int>(Models::Subcomponent::kSolid) + 1)->setEnabled(true);
    m_subcomponentTypeButtonGroup->button(static_cast<int>(Models::Subcomponent::kComplement) + 1)->setEnabled(true);
    m_subcomponentTypeButtonGroup->button(static_cast<int>(Models::Subcomponent::kHole) + 1)->setEnabled(true);

    for (std::vector<Models::Subcomponent::SubcomponentType>::const_iterator it = types.begin(); it != types.end(); ++it)
    {
        m_subcomponentTypeButtonGroup->button(static_cast<int>(*it) + 1)->setEnabled(false);
        if (*it == m_subcomponentType)
            m_subcomponentTypeButtonGroup->button(static_cast<int>(Models::Subcomponent::kSolid) + 1)->setChecked(true);
    }
}

void SubcomponentTypeWidget::handleSubcomponentTypeChoice(int subcomponentTypeChoiceId)
{
    if (static_cast<Models::Subcomponent::SubcomponentType>(subcomponentTypeChoiceId - 1) != m_subcomponentType)
    {
        m_subcomponentType = static_cast<Models::Subcomponent::SubcomponentType>(subcomponentTypeChoiceId - 1);
        emit subcomponentTypeChanged();
    }
}

void SubcomponentTypeWidget::initialize()
{
    this->setupUi(this);

    m_subcomponentTypeButtonGroup->addButton(m_solidRadioButton, static_cast<int>(Models::Subcomponent::kSolid) + 1);
    m_subcomponentTypeButtonGroup->addButton(m_complementRadioButton, static_cast<int>(Models::Subcomponent::kComplement) + 1);
    m_subcomponentTypeButtonGroup->addButton(m_holeRadioButton, static_cast<int>(Models::Subcomponent::kHole) + 1);

    m_subcomponentTypeButtonGroup->button(static_cast<int>(m_subcomponentType) + 1)->setChecked(true);

    connect(m_subcomponentTypeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(handleSubcomponentTypeChoice(int)));
}

The actual error messages I am receiving are:

../lib/libMeshAndGeometry.a(AddAdvancedDialog.o)(.gnu.linkonce.t._ZN20Ui_AddAdvancedDialog7setupUiEP7QDialog+0x955): In function `Ui_AddAdvancedDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddAdvancedDialog.o)(.gnu.linkonce.t._ZN20Ui_AddAdvancedDialog7setupUiEP7QDialog+0x960): In function `Ui_AddAdvancedDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddAdvancedDialog.o)(.gnu.linkonce.t._ZN20Ui_AddAdvancedDialog7setupUiEP7QDialog+0x99b): In function `Ui_AddAdvancedDialog::setupUi(QDialog*)':
: undefined reference to `SubcomponentTypeWidget::initialize()'
../lib/libMeshAndGeometry.a(AddBoxDialog.o)(.gnu.linkonce.t._ZN15Ui_AddBoxDialog7setupUiEP7QDialog+0xfe8): In function `Ui_AddBoxDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddBoxDialog.o)(.gnu.linkonce.t._ZN15Ui_AddBoxDialog7setupUiEP7QDialog+0xff3): In function `Ui_AddBoxDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddBoxDialog.o)(.gnu.linkonce.t._ZN15Ui_AddBoxDialog7setupUiEP7QDialog+0x102e): In function `Ui_AddBoxDialog::setupUi(QDialog*)':
: undefined reference to `SubcomponentTypeWidget::initialize()'
../lib/libMeshAndGeometry.a(AddConeDialog.o)(.gnu.linkonce.t._ZN16Ui_AddConeDialog7setupUiEP7QDialog+0x7ef): In function `Ui_AddConeDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddConeDialog.o)(.gnu.linkonce.t._ZN16Ui_AddConeDialog7setupUiEP7QDialog+0x7fa): In function `Ui_AddConeDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddConeDialog.o)(.gnu.linkonce.t._ZN16Ui_AddConeDialog7setupUiEP7QDialog+0x835): In function `Ui_AddConeDialog::setupUi(QDialog*)':
: undefined reference to `SubcomponentTypeWidget::initialize()'
../lib/libMeshAndGeometry.a(AddCylinderDialog.o)(.gnu.linkonce.t._ZN20Ui_AddCylinderDialog7setupUiEP7QDialog+0x9c4): In function `Ui_AddCylinderDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddCylinderDialog.o)(.gnu.linkonce.t._ZN20Ui_AddCylinderDialog7setupUiEP7QDialog+0x9cf): In function `Ui_AddCylinderDialog::setupUi(QDialog*)':
: undefined reference to `vtable for SubcomponentTypeWidget'
../lib/libMeshAndGeometry.a(AddCylinderDialog.o)(.gnu.linkonce.t._ZN20Ui_AddCylinderDialog7setupUiEP7QDialog+0xa0a): In function `Ui_AddCylinderDialog::setupUi(QDialog*)':

All of my makefiles have been generated from my .pro file using qmake. The main make files, the main .pro file, and the widgets and MeshAndGeometry make and .pro files are attached here as an archive. One of the .ui files is attached here.

I have tried a number of things.

  1. I am sure this is not a stale object file issue. I have built this from scratch and I still have the the problem.
  2. I checked all of my capitalization issues. One of the problems I have noticed with doing most of this on Windows and then moving it to Linux is that people make mistakes with capitalization, and Windows doesn't care about capitalization.
  3. I ran nm -a -C SubcomponentTypeWidget.o to see if the necessary vtable was there, and it wasn't. However, the 'missing' methods were there.
  4. Creating a virtual destructor does not force vtable generation for SubcomponentTypeWidget.
  5. I have tried removing large chunks of SubcomponentTypeWidget's functionality. This results in removing the specific linker error messages for methods, but it does not remove the undefined reference to vtable message. I have removed everything from SubcomponentTypeWidget other than the constructor, and in this case I still receive the "undefined reference to vtable" message, but without any mention to specific methods we are looking for.
  6. Changing the order of which widgets and MeshingAndGeometry are linked in does not help.
  7. I have tried gcc versions 3.4.6 20060404 and 4.1.2 20080704.

Help me, Obi-Wan Kenobi. You're my only hope.

Thank you all very, very much,

-Brian J. Stinar-


went through your codes the error most likely arises from the following statement:

=======================================================
void SubcomponentTypeWidget::initialize()
{
    this->setupUi(this);
    //rest of codes
}
=======================================================

you are sort of breaking the structure of Qt by making SubcomponentTypeWidget a subclass of Ui::SubcomponentTypeWidget. You are actually using yourself to setup a UI of yourself in this case. Coupled that with the fact that you are using multiple class inheritance, you are just confusing the compiler on which virtual method to refer to during runtime.

Instead of subclassing Ui::SubcomponentTypeWidget, just make it a private variable in SubcomponentTypeWidget

//SubcomponentTypeWidget.h
     private:
         Ui::SubcomponentTypeWidge ui;

implement the following in your init function and you should be good to go

void SubcomponentTypeWidget::initialize()
{
    ui.setupUi(this);
    //rest of codes
}


My problem was with solution point number six. I actually did NOT change this order correctly. I was changing the order in the INCPATH instead of the order in the LIBS.

After adding the line MeshAndGeometry.depends = widgets to my master.pro file, running qmake, and running make, this problem went away.

Thank everyone very much for their comments and help.

-Brian J. Stinar-

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜