在写代码中经常发现有些类中的成员函数(包括nonvirtual func, virtual func and pure virtual func, static func)并未实现,但仍然能够正常的编译链接通过?
没想太明白,于是做了一下试验。
1)先用纯虚函数做试验
#include "stdafx.h"
#include <iostream>
using namespace std;
class CA
{
public:
virtual void Display() = 0;
};
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
编译链接正常
2)用虚函数
class CA
{
public:
virtual void Display();
}
编译链接正常
class CA
{
public:
void Display();
};
编译链接正常
4)用静态函数
class CA
{
public:
static void Display();
};
编译链接正常
发现其实定义成任何一种成员函数都没有问题,都能够正常的编译链接通过。
那么什么情况下会出现无法编译链接通过呢?
那很明显应该在类实例化或调用函数时,仍然对上面4种函数进行试验。
1)使用纯虚函数
#include "stdafx.h"
#include <iostream>
using namespace std;
class CA
{
public:
virtual void Display() = 0;
};
int _tmain(int argc, _TCHAR* argv[])
{
CA a;
return 0;
}
编译失败,报错 error C2259: 'CA' : cannot instantiate abstract class
class CA
{
public:
virtual void Display();
};
链接失败,报错error LNK2001: unresolved external symbol "public: virtual void __thiscall CA::Display(void)" (?Display@CA@@UAEXXZ)
3)使用一般函数
#include "stdafx.h"
#include <iostream>
using namespace std;
class CA
{
public:
void Display();
};
int _tmain(int argc, _TCHAR* argv[])
{
CA a;
return 0;
}
编译链接通过,就说明CA对象a可以实例化
很显然,如果调用a.Display(),链接自然会失败
4)使用static函数
#include "stdafx.h"
#include <iostream>
using namespace std;
class CA
{
public:
static void Display();
};
int _tmain(int argc, _TCHAR* argv[])
{
CA a;
return 0;
}
同一般函数一样,编译链接通过,CA对象可以实例化。
但调用CA::Disply(),链接会失败。
通过以上试验可以对类中定义的成员函数有个一般性的结论了:
1)该类未有任何调用,则不影响任何编译链接
2)当类实例化时,纯虚函数和虚函数无法实例化,原因分别为编译时和链接时报错,这跟vtable相关;一般函数和静态函数可以实例化
3)当类实例化并调用对应的方法时,这个时候肯定必须实现方法了,要不程序怎样调用对应函数指针
以上就是分析的结果。