[1]中有这样一份代码
#include <iostream>
using namespace std;
class Base
{
public:
Base();
void f1();//member function
virtual void f2();//virtual function
virtual void f3()=0;//pure virtual function
virtual ~Base();//virtual destructor function
};
class Derive:public Base
{
public:
Derive();
void f1();
void f2();
void f3();
virtual ~Derive();
};
int main () {
Derive d;
return 0;
}
运行时,出现如下错误:
undefined reference to Derive::Derive()
undefined reference to Derive::~Derive()
其实这份代码中有2处错误
显式构造函数需要加空函数体(null bodies)
base类的虚函数也需要加函数体
报错的直接原因则是:找不到Derive类构造、析构函数的定义。因为没有定义、只有申明的函数是无法使用的。
简单起见,我们Derive构造析构函数加上花括号(空函数体)Derive(){};
接着运行出现:
现在找不到Base构造、析构函数的实现,还找不到虚函数表:undefined reference to vtable for Derive
找不到vtable问题便是[2]中提到的
more obscure messages from the Gnu C++ compiler - or rather from the loader
解决方法是给Base中虚函数f2()也加上函数体。而由于Derive继承之后的f2仍然是虚函数,所以Derive::f2()也需要加上花括号。
这是因为链接器linker需要将虚函数表vtable 放入某个object file,但是linker无法找到正确的object文件[3]。所以虚函数要有定义
而成员函数f1()即时没有定义,在编译过程中也不会报错。当然你要强行调用这个没定义的函数也会同样报错。
最后总结一下:
显示申明构造函数、析构函数一定要有定义
C++类继承过程中父类的普通成员函数可以没定义。但是虚函数一定要有定义
最终版的代码:
class Base
{
public:
Base(){};
void f1();//member function
virtual void f2(){};//virtual function
virtual void f3()=0;//pure virtual function
virtual ~Base(){};//virtual destructor function
};
class Derive:public Base
{
public:
Derive(){};
void f1();
void f2(){};
void f3(){};
virtual ~Derive(){};
};
Reference
[1] 抽象类 http://www.cnblogs.com/dongsh...
[2] vtables http://www.cnblogs.com/longdo...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。