簡體   English   中英

帶有虛擬功能的未解析外部符號

[英]Unresolved External Symbol with virtual functions

我試圖通過使用qt設計模式中的示例來查看虛擬函數的行為

在這里,我有一個頭文件,其中定義了2個類:

#ifndef ABCLASSES_H
#define ABCLASSES_H
#include <QTextStream>

class A
{
public:
    virtual ~A()
    {

    }
    virtual void foo(QTextStream& out);
    virtual void bar(QTextStream& out);
};

class B: public A
{
public:
    void foo(QTextStream& out);
    void bar(QTextStream& out);
};

#endif // ABCLASSES_H

這是這些類的源文件

#include "abclasses.h"

void A::foo(QTextStream& out)
{
    out << "A's foo" << endl;
    bar(out);
}

void A::bar(QTextStream& out)
{
    out << "A's bar" << endl;
}

void B::foo(QTextStream& out)
{
    out << "B's foo" << endl;
    A::bar(out);
}

void B::bar(QTextStream& out)
{
    out << "B's bar" << endl;
}

問題是我無法從這些定義中創建或使用任何類。 我得到的錯誤是

main.obj:-1:錯誤:LNK2001:未解析的外部符號“ public:虛擬void __cdecl A :: foo(QTextStream類&)”(?foo @ A @@ UEAAXAEAVQTextStream @@@@ Z)

main.obj:-1:錯誤:LNK2001:無法解析的外部符號“ public:虛擬void __cdecl A :: bar(類QTextStream&)”(?bar @ A @@ UEAAXAEAVQTextStream @@@@ Z)

因為我對虛函數沒有太多了解。 我認為可能需要重新聲明B類中的函數,但這無濟於事,並在我的日志中增加了2個錯誤。

main.obj:-1:錯誤:LNK2001:無法解析的外部符號“ public:虛擬void __cdecl B :: foo(class QTextStream&)”(?foo @ B @@ UEAAXAEAVQTextStream @@@@ Z)

main.obj:-1:錯誤:LNK2001:無法解析的外部符號“ public:虛擬void __cdecl B :: bar(類QTextStream&)”(?bar @ B @@ UEAAXAEAVQTextStream @@@@ Z)

書中的示例只是在聲明了函數(在同一文件中)后才實現函數,這似乎可行。 我想知道為什么我的不起作用以及是否有解決方法

編輯:項目文件使用以下設置:

#-------------------------------------------------
#
# Project created by QtCreator 2015-08-23T11:53:16
#
#-------------------------------------------------

QT       += core

QT       -= gui

TARGET = untitled1
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app


SOURCES += main.cpp \
    student.cpp \
    abclasses.cpp

HEADERS += \
    student.h \
    abclasses.h

我不得不說,在構建,鏈接東西時我沒有太多想法,但我現在不應該將重點放在一個小項目上。 因為abclases.cpp是源代碼,所以我認為它用於構建過程。

student.h和.cpp與我在同一項目中進行的另一個試用有關。 他們現在沒有被積極使用,下面是main.cpp

#include <QCoreApplication>
#include <QTextStream>
//#include "student.h"
#include "abclasses.h"

//void finish(Student& student)
//{
//    QTextStream cout(stdout);
//    cout << "The following " << student.getClassName()
//         << "has applied for graduation" << endl
//         << student.toString() << endl;
//}

int main() {
    QTextStream cout(stdout);
    B bobj;
//    A *aptr = &bobj;
//    aptr->foo(cout);
//    cout << "-------------" << endl;
//    A aobj = *aptr;
//    aobj.foo(cout);
//    cout << "-------------" << endl;
//    aobj = bobj;
//    aobj.foo(cout);
//    cout << "-------------"<< endl;
//    bobj.foo(cout);
}

編輯2:更新了過時的錯誤消息,更新了abclasses.h

能否請您更新問題? 正如您說的那樣,您已經對B類進行了修改,請對其進行更新。 即使是新遇到的錯誤。

private: virtual void __cdecl B::bar(class QTextStream &)" (?

由於此錯誤,類B中的bar函數似乎是私有的。

好吧,這是挖掘互聯網解決類似問題之后的結果。 qt的創建者有時不能真正告訴它是否應該更新“ make”文件,我對此有些了解,因此在進行了一些大的更改后使用了“ clean”。 但問題是干凈或重建無法按我希望的那樣進行。 因此,在提出了一些建議之后,我手動刪除了構建文件夾,現在它可以編譯並正常運行。

由於makefile與.pro文件相比過時,因此abclassess.cpp文件未編譯。 右鍵單擊Qt Creator中最頂層的項目節點,然后選擇Run qmake 然后再次構建項目。

不幸的是,這是Windows上Qt Creator和qmake之間不良的交互。 在該平台上,qmake生成三個makefile: MakefileMakefile.releaseMakefile.debug 不幸的是,只有頂級makefile在.pro文件和makefile之間具有適當的依賴關系:每當項目文件更改時,make就會通過調用qmake來自動重新生成makefile。 通常這不會有問題,因為當您手動構建時,會在頂部的Makefile上調用nmake / jom

但是Qt Creator分別根據發布/調試版本的需要直接調用Makefile.releaseMakefile.debug 這將繞過僅在基本Makefile存在的makefile再生規則。 正是這種交互導致錯誤/行為不當(不幸地)影響了Windows上的Qt Creator的每個用戶。

因此,例如,每次添加或修改源文件時,都必須在對項目文件的每次更改之后調用qmake

有一個簡單的解決方法-添加一個構建步驟,以將基本Makefile調用到項目配置的構建中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM