c++編譯報錯error LNK2001: 無法解析的外部符號

c++編譯報錯error LNK2001: 無法解析的外部符號

這個報錯是真的迷惑,一般會提示到無法解析的一個函數或者一個變量。
如果是變量的話,一般是靜態成員變量static typename xxx沒有經過初始化便使用(不是類的數據成員的話vs會報錯)。
原因是我們如果只是聲明靜態變量而沒有初始化的話,編譯器是不會爲這個靜態變量分配空間的,只有當初始化靜態變量之後,編譯器纔會在內存的靜態區給這個變量分配空間,這樣程序才能在數據區找到這個變量並繼續使用。
如果是函數的話,我目前遇到的情況有:
1)只聲明瞭函數,但沒有完成定義;
2)今天遇到的,調用派生類的函數時,基類的同命虛函數沒有完成定義。

//Declaration.h
class myExc 
	{
	protected:
		double a;
		double b;
	public:
		myExc() :logic_error(""){}
		virtual void show();
	};
	
	class bad_gmean :myExc
	{
	public:
		bad_gmean(){}
		void show(){ cout << "gmean( " << a << " , " << b << " ): invalid arguments: a < 0 or b < 0\n"; }
	};

	class bad_hmean :myExc
	{
	public:
		bad_hmean(){}
		void show(){ cout << "hmean( " << a << " , " << b << " ): invalid arguments: a = -b\n"; }
	};

上圖可以看到派生類重寫了基類的void show()函數,但基類的void show()並沒有進行內聯定義。

//main.cpp
/*
...
*/
catch (myExc &b)
		{
			b.show();
			cout << "Exception type: " << typeid(b).name() << endl;
			cout << "Try again.\n";
			continue;
		}
/*
...
*/
		

上圖可以看到主函數裏,我們通過基類引用的方式去調用派生類的show()函數,雖然沒有直接使用基類的show(),但是,使用基類引用的方式去調用派生類函數的方式屬於動態聯編,是在程序運行的時候的完成,而在程序的編譯階段,編譯器還是認爲這裏調用了基類的show()函數,因此報錯。
修改方式很簡單,在確保不會調用到基類方法的前提下,可以直接內聯定義基類函數show():

virtual void show() {}

或者將函數聲明爲純虛函數,相應的基類也將變成抽象基類:

virtual void show() = 0

如果要使用基類的show函數完成其他操作,則要對基類的show函數進行相應的定義。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章