【问题标题】:VTable Not Generated未生成 VTable
【发布时间】:2011-08-10 12:01:43
【问题描述】:

首先,非常感谢您花时间看我的问题。其次,我已经阅读了this,并且我的班级没有任何我忘记包含的虚拟方法。在描述了我的问题后,我将回顾我尝试过的其他事情。

当我使用 gcc 版本 3.4.6 20060404 构建我的代码时,我收到一个 undefined reference to `vtable for SubcomponentTypeWidget' 错误。Visual Studio 2005 没有问题。我喜欢 Linux,但我目前的政治状况已将它委托给经常遭受虐待的红发继子。希望通过我们的力量结​​合,我可以解决这个问题。

我使用的是 Qt 版本 4.6.2。我在 Red Hat 4 上使用 gcc 3.4.6 20060404。

这是我的标题:

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

我所有的 makefile 都是使用 qmake 从我的 .pro 文件生成的。主要的 make 文件、主要的 .pro 文件、小部件和 MeshAndGeometry make 和 .pro 文件作为存档附加到here。其中一个 .ui 文件附在 here 上。

我已经尝试了很多东西。

  1. 我确信这不是一个过时的对象文件问题。我是从头开始构建的,但问题仍然存在。
  2. 我检查了所有大小写问题。我注意到在 Windows 上进行大部分操作然后将其转移到 Linux 的问题之一是人们在大小写方面会犯错误,而 Windows 并不关心大小写。
  3. 我运行了 nm -a -C SubcomponentTypeWidget.o 来查看是否存在必要的 vtable,但实际上没有。但是,“缺失”的方法在那里。
  4. 创建虚拟析构函数不会强制为 SubcomponentTypeWidget 生成 vtable。
  5. 我已经尝试删除大部分 SubcomponentTypeWidget 的功能。这会导致删除方法的特定链接器错误消息,但不会删除对 vtable 消息的未定义引用。我已经从 SubcomponentTypeWidget 中删除了除构造函数之外的所有内容,在这种情况下,我仍然收到“未定义对 vtable 的引用”消息,但没有提及我们正在寻找的具体方法。
  6. 更改小部件和 MeshingAndGeometry 的链接顺序无济于事。
  7. 我已经尝试过 gcc 版本 3.4.6 20060404 和 4.1.2 20080704。

帮帮我,欧比旺·克诺比。你是我唯一的希望。

非常非常感谢大家,

-布莱恩·J·斯蒂纳尔-

【问题讨论】:

  • 尝试在SubcomponentTypeWidget.h 标头中包含QObject 类。
  • 就在那里,在 Q_PROPERTY 之上和 SubcomponentTypeWidget 类之下:public QWidget, public Ui::SubcomponentTypeWidget {
  • @Brian 我说标题不是宏。
  • 我有两个建议给你,尝试再次重新运行 qmake,尝试搜索 vtable 定义的位置,然后包含内容它的标题,我遇到了类似的问题。
  • 当您收到上述错误消息时,您能解释一下您究竟要编译什么吗?您的项目由几个子目标组成,不清楚是哪个子目标产生了错误。例如粘贴编译器/链接器命令会很有帮助。看起来它应该是试图在libMeshAndGeometry.a 中链接的东西,但您包含在 .zip 文件中的所有 makefile 都没有这样做。

标签: linux qt compiler-construction build g++


【解决方案1】:

查看您的代码,错误很可能来自以下语句:

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

您通过使 SubcomponentTypeWidget 成为 Ui::SubcomponentTypeWidget 的子类来破坏 Qt 的结构。在这种情况下,您实际上是在使用自己来设置自己的 UI。再加上您使用多类继承这一事实,您只会混淆编译器在运行时引用哪个虚拟方法。

不用子类化 Ui::SubcomponentTypeWidget,只需将其设为 SubcomponentTypeWidget 中的私有变量

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

在您的 init 函数中实现以下内容,您应该一切顺利

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

【讨论】:

  • 我将在我的全新重建完成后直接尝试这个。谢谢。
  • 执行此操作后,我仍然收到相同的错误消息。非常奇怪的是,这两个输出上的 nm -a -C SubcomponentTypeWidget.o 是相同的。这根本没有任何意义,如果我是 Ui_SubcomponentTypeWidget 与我包含 Ui_SubcomponentTypeWidget ,这些不应该有所不同吗?
【解决方案2】:

我的问题是 解决方案 第六点。我实际上没有正确更改此顺序。我正在更改 INCPATH 中的顺序而不是 LIBS 中的顺序。

在我的 master.pro 文件中添加 MeshAndGeometry.depends = widgets 行,运行 qmake 并运行 make 后,这个问题就消失了。

非常感谢大家的cmets和帮助。

-Brian J. Stinar-

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    相关资源
    最近更新 更多