首先,非常感谢您抽出宝贵时间来研究我的问题。其次,我已阅读this,并且我的课程没有忘记包含的任何虚拟方法。描述问题后,我将介绍其他尝试过的内容。
当我使用gcc版本3.4.6 20060404构建代码时,出现对`vtable for SubcomponentTypeWidget'的未定义引用。VisualStudio 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。
我尝试了很多事情。
我确定这不是陈旧的目标文件问题。我是从头开始构建的,但仍然有问题。
我检查了所有大写问题。我注意到在Windows上执行大多数操作然后再将其转移到Linux时遇到的问题之一是,人们在使用大写字母时会犯错误,而Windows并不关心大写字母。
我运行nm -a -C SubcomponentTypeWidget.o来查看是否有必要的vtable,而没有。但是,“丢失”方法在那里。
创建虚拟析构函数不会强制为SubcomponentTypeWidget生成vtable。
我试图删除SubcomponentTypeWidget的功能的大块。这将导致删除方法的特定链接器错误消息,但不会删除对vtable消息的未定义引用。我从SubcomponentTypeWidget中删除了除构造函数以外的所有内容,在这种情况下,我仍然收到“未定义对vtable的引用”消息,但未提及我们正在寻找的特定方法。
更改小部件和MeshingAndGeometry链接的顺序无济于事。
我已经尝试了gcc版本3.4.6 20060404和4.1.2 20080704。
Obi-Wan Kenobi,帮帮我。你是我唯一的希望。
非常非常感谢大家,
-布莱恩·斯蒂纳(Brian J.
最佳答案
通过您的代码,错误很可能是由以下语句引起的:
=======================================================
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
}