在VisualStudio下開發C++程序常遇到鏈接問題就是:LNK2019 無法解析外部符號.
這個問題一般我們認為是沒有將引用的代碼鏈接到當前項目造成,也有例外,就是下面我要說的預聲明類導致的。
為了加快編譯速度,我們經常選擇在頭文件中預聲明類占個名字用於指針,在代碼定義文件中再去包含完整的類聲明。
foo.h:
class foo
{
public:
void call(){};
}
bar.h:
class foo;
foo* f=0;
bar.cpp:
#include "bar.h"
#include "foo.h"
int main(){f->call();return 0;}
當遇到編譯單元(一般指cpp文件)出現關聯引用(A用B,B用C)時,兩次引用其中一個沒有包含最終引用對象(C)的聲明時也會發生“無法解析外部符號.”
例如:
foo.h:
class foo
{
public:
void call(){};
}
bar.h:
class foo;
void barcall(foo* f=0);
bar.cpp:
#include "bar.h"
foo* store;
void barcall(foo* arg)
{
store = arg;
}
main.cpp:
#include "foo.h"
#include "bar.h"
int main()
{
barcall(0);
return 0;
}
編譯時的main.cpp中的foo類是完整的聲明,而bar.cpp中的foo類僅僅是一個空的結構(預定義的),所以編譯器會認定他們是不同的結構,導致找不到要找的那個符號。
此例中是因為bar.cpp中沒有包含foo.h,所以foo的結構僅僅是個空結構,與main.cpp中對barcall引用的foo結構是不同的,產生找不到符號的鏈接錯誤。
解決辦法是在bar.cpp中包含foo.h來得到foo的完整聲明。