[英]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: Makefile
, Makefile.release
和Makefile.debug
。 不幸的是,只有頂級makefile在.pro
文件和makefile之間具有適當的依賴關系:每當項目文件更改時,make就會通過調用qmake來自動重新生成makefile。 通常這不會有問題,因為當您手動構建時,會在頂部的Makefile
上調用nmake / jom 。
但是Qt Creator分別根據發布/調試版本的需要直接調用Makefile.release
或Makefile.debug
。 這將繞過僅在基本Makefile
存在的makefile再生規則。 正是這種交互導致錯誤/行為不當(不幸地)影響了Windows上的Qt Creator的每個用戶。
因此,例如,每次添加或修改源文件時,都必須在對項目文件的每次更改之后調用qmake 。
有一個簡單的解決方法-添加一個構建步驟,以將基本Makefile
調用到項目配置的構建中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.