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函数进行相应的定义。

发布了16 篇原创文章 · 获赞 10 · 访问量 4924

猜你喜欢

转载自blog.csdn.net/weixin_44826484/article/details/104300070