VTable не генерируется - PullRequest
       28

VTable не генерируется

0 голосов
/ 21 апреля 2011

Прежде всего, большое спасибо, что нашли время взглянуть на мой вопрос. Во-вторых, я прочитал this , и в моем классе нет никаких виртуальных методов, которые я забыл включить. После того, как я опишу свою проблему, я перейду к дополнительным вещам, которые я пробовал.

Я получаю неопределенную ссылку на `vtable for SubcomponentTypeWidget ', когда я строю свой код с использованием gcc версии 3.4.6 20060404. Visual Studio 2005 не имеет проблем. Я люблю Linux, но моя текущая политическая ситуация делегировала его рыжеволосому пасынку, который регулярно подвергается насилию. Надеюсь, что благодаря нашим силам я смогу это исправить.

Я использую Qt версии 4.6.2. Я использую gcc 3.4.6 20060404 в Red Hat 4.

Это мой заголовок:

#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();

protected slots:
    void handleSubcomponentTypeChoice(int subcomponentTypeChoiceId);

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

#endif // SubcomponentTypeWidget_h

Реализация здесь:

#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)));
}

Фактические сообщения об ошибках, которые я получаю:

../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*)':

Все мои make-файлы были сгенерированы из моего .pro-файла с использованием qmake. Основные файлы make, основной файл .pro, а также файлы make и виджеты MeshAndGeometry и .pro прикрепляются здесь в виде архива. Один из файлов .ui прикреплен здесь .

Я пробовал несколько вещей.

  1. Я уверен, что это не проблема устаревших объектных файлов. Я построил это с нуля, и у меня все еще есть проблема.
  2. Я проверил все проблемы с капитализацией. Одна из проблем, которые я заметил, выполнив большую часть этого в Windows и затем переместив его в Linux, заключается в том, что люди допускают ошибки с использованием заглавных букв, а Windows не заботится о заглавных буквах.
  3. Я запустил nm -a -C SubcomponentTypeWidget.o, чтобы посмотреть, был ли необходимый vtable, и его не было. Однако «отсутствующие» методы были там.
  4. Создание виртуального деструктора не вызывает генерацию vtable для SubcomponentTypeWidget.
  5. Я попытался удалить большие фрагменты функциональности SubcomponentTypeWidget. Это приводит к удалению определенных сообщений об ошибках компоновщика для методов, но не удаляет неопределенную ссылку на сообщение vtable. Я удалил все из SubcomponentTypeWidget, кроме конструктора, и в этом случае я все еще получаю сообщение «неопределенная ссылка на vtable», но без какого-либо упоминания конкретных методов, которые мы ищем.
  6. Изменение порядка связывания виджетов и MeshingAndGeometry не помогает.
  7. Я пробовал gcc версии 3.4.6 20060404 и 4.1.2 20080704.

Помоги мне, Оби-Ван Кеноби. Ты моя единственная надежда.

Большое спасибо всем вам,

-Брайан Дж. Стинар-

Ответы [ 2 ]

0 голосов
/ 22 апреля 2011

Моя проблема была с решением точкой номер шесть.Я на самом деле НЕ изменил этот порядок правильно.Я менял порядок в INCPATH вместо порядка в LIBS.

После добавления строки MeshAndGeometry.depends = widgets в файл master.pro, запуска qmake и запуска make эта проблема исчезла.

Большое спасибо всем за комментарии и помощь.

-Брайан Дж. Стинар-

0 голосов
/ 21 апреля 2011

прошел через ваши коды, ошибка, скорее всего, возникает из следующего утверждения:

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

вы как бы разбиваете структуру Qt, делая SubcomponentTypeWidget подклассом Ui :: SubcomponentTypeWidget.В этом случае вы фактически используете себя для настройки своего пользовательского интерфейса.В сочетании с тем фактом, что вы используете множественное наследование классов, вы просто путаете компилятор, к которому относится виртуальный метод во время выполнения.

Вместо создания подкласса Ui :: SubcomponentTypeWidget просто сделайте его частной переменной вSubcomponentTypeWidget

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

реализует следующее в вашей функции инициализации, и вы должны хорошо идти

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