虚函数导致链接错误

时间:2014-11-28 13:14:06

标签: c++ qt kde

当我在项目中使用外部.h文件时,我正在努力解决问题。

我正在使用Qt5和MSVC2012。在我的主文件中,我包含了来自KDE应用程序的头文件。我在.pro文件中放了一些INCLUDEPATH来正确链接。

我遇到麻烦的代码如下:

main.cpp
...
#include <Doc.h>

int main(int argc, char *argv[])
...

Doc.h 属于KDE应用程序源代码。包含该文件包括KDE应用程序源代码中的多个目录中的许多其他文件。

目前, KUndo2Stack.h KUndo2Stack.cpp 文件是我三天以来一直在努力争取的文件。

当我运行QMake并编译时,由于在这些文件中定义并实现的 KUndo2QStack 类中的虚函数的未解析外部,我得到了链接2001错误。这是一个摘录:

#ifndef QT_NO_UNDOSTACK

class KUNDO2_EXPORT KUndo2QStack : public QObject
{
    Q_OBJECT
//    Q_DECLARE_PRIVATE(KUndo2QStack)
    Q_PROPERTY(bool active READ isActive WRITE setActive)
    Q_PROPERTY(int undoLimit READ undoLimit WRITE setUndoLimit)

public:
    explicit KUndo2QStack(QObject *parent = 0);
    virtual ~KUndo2QStack();
    void clear();

    void push(KUndo2Command *cmd);

    bool canUndo() const;
    bool canRedo() const;
    QString undoText() const;
    QString redoText() const;

    int count() const;
    int index() const;
    QString actionText(int idx) const;
    QString text(int idx) const;

#ifndef QT_NO_ACTION
    QAction *createUndoAction(QObject *parent) const;
    QAction *createRedoAction(QObject *parent) const;
#endif // QT_NO_ACTION

    bool isActive() const;
    bool isClean() const;
    int cleanIndex() const;

    void beginMacro(const QString &text);
    void endMacro();

    void setUndoLimit(int limit);
    int undoLimit() const;

    const KUndo2Command *command(int index) const;

public Q_SLOTS:
    void setClean();
    virtual void setIndex(int idx);
    virtual void undo();
    virtual void redo();
    void setActive(bool active = true);

Q_SIGNALS:
    void indexChanged(int idx);
    void cleanChanged(bool clean);
    void canUndoChanged(bool canUndo);
    void canRedoChanged(bool canRedo);
    void undoTextChanged(const QString &undoActionText);
    void redoTextChanged(const QString &redoActionText);

private:
    // from QUndoStackPrivate
    QList<KUndo2Command*> m_command_list;
    QList<KUndo2Command*> m_macro_stack;
    int m_index;
    int m_clean_index;
    KUndo2Group *m_group;
    int m_undo_limit;

    // also from QUndoStackPrivate
    void setIndex(int idx, bool clean);
    bool checkUndoLimit();

    Q_DISABLE_COPY(KUndo2QStack)
    friend class KUndo2Group;
};

class KUNDO2_EXPORT KUndo2Stack : public KUndo2QStack
{
public:
    explicit KUndo2Stack(QObject *parent = 0);

    // functions from KUndoStack
    QAction* createRedoAction(KActionCollection* actionCollection, const QString& actionName = QString());
    QAction* createUndoAction(KActionCollection* actionCollection, const QString& actionName = QString());
};

#endif // QT_NO_UNDOSTACK

请注意,未解析的链接仅适用于虚拟功能。这些功能如下实现:

KUndo2QStack::~KUndo2QStack()
{
#ifndef QT_NO_UNDOGROUP
    if (m_group != 0)
        m_group->removeStack(this);
#endif
    clear();
}

void KUndo2QStack::undo()
{
    if (m_index == 0)
        return;

    if (!m_macro_stack.isEmpty()) {
        qWarning("KUndo2QStack::undo(): cannot undo in the middle of a macro");
        return;
    }

    int idx = m_index - 1;
    m_command_list.at(idx)->undo();
    setIndex(idx, false);
}

void KUndo2QStack::redo()
{
    if (m_index == m_command_list.size())
        return;

    if (!m_macro_stack.isEmpty()) {
        qWarning("KUndo2QStack::redo(): cannot redo in the middle of a macro");
        return;
    }

    m_command_list.at(m_index)->redo();
    setIndex(m_index + 1, false);
}

void KUndo2QStack::setIndex(int idx)
{
    if (!m_macro_stack.isEmpty()) {
        qWarning("KUndo2QStack::setIndex(): cannot set index in the middle of a macro");
        return;
    }

    if (idx < 0)
        idx = 0;
    else if (idx > m_command_list.size())
        idx = m_command_list.size();

    int i = m_index;
    while (i < idx)
        m_command_list.at(i++)->redo();
    while (i > idx)
        m_command_list.at(--i)->undo();

    setIndex(idx, false);
}

我已经把这个问题颠倒过来寻找网络上的答案,而且我唯一一次得到的东西是当我删除虚拟关闭所有相关功能的时候。它取消了错误,但是我在类 KUndo2Stack 的析构函数中得到了一个未解决的link2019错误(请参阅上面的代码)。我所讨论的析构函数是默认的,你不会看到它的任何定义或实现。

我需要一些帮助才能了解实际情况以及如何解决问题。

谢谢!

更新

确切的错误消息是:

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl KUndo2QStack::metaObject(void)const " (?metaObject@KUndo2QStack@@UEBAPEBUQMetaObject@@XZ)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __cdecl KUndo2QStack::qt_metacast(char const *)" (?qt_metacast@KUndo2QStack@@UEAAPEAXPEBD@Z)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __cdecl KUndo2QStack::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@KUndo2QStack@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl KUndo2QStack::setIndex(int)" (?setIndex@KUndo2QStack@@UEAAXH@Z)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl KUndo2QStack::undo(void)" (?undo@KUndo2QStack@@UEAAXXZ)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void __cdecl KUndo2QStack::redo(void)" (?redo@KUndo2QStack@@UEAAXXZ)

main.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __cdecl KUndo2Stack::~KUndo2Stack(void)" (__imp_??1KUndo2Stack@@UEAA@XZ) referenced in function "public: virtual void * __cdecl KUndo2Stack::`scalar deleting destructor'(unsigned int)" (??_GKUndo2Stack@@UEAAPEAXI@Z)

debug\whitehall_0_2.exe:-1: error: LNK1120: 7 unresolved externals

更新

Q_OBJECT 添加到KUndo2Stack类后,与KUndo2QStack的qmetaobject相关的链接错误消失了。这次出现的相同错误与 KUndo2Stack 类有关

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl KUndo2Stack::metaObject(void)const " (?metaObject@KUndo2Stack@@UEBAPEBUQMetaObject@@XZ)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __cdecl KUndo2Stack::qt_metacast(char const *)" (?qt_metacast@KUndo2Stack@@UEAAPEAXPEBD@Z)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __cdecl KUndo2Stack::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@KUndo2Stack@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)

其他错误保持不变。

0 个答案:

没有答案