C++虚函数与纯虚函数

在面向对象程序设计领域,C++、Object Pascal 等语言中有虚函数(英语:virtual function)或虚方法(英语:virtual method)的概念。这种函数或方法可以被子类继承和覆盖,通常使用动态调度实现。

纯虚函数或纯虚方法是一个需要被非抽象的派生类覆盖(override)的虚函数. 包含纯虚方法的类被称作抽象类; 抽象类不能被直接实例化。 一个抽象基类的一个子类只有在所有的纯虚函数在该类(或其父类)内给出实现时, 才能直接实例化. 纯虚方法通常只有声明(签名)而没有定义(实现),但有特例情形要求纯虚函数必须给出函数体定义.

虚函数示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# include <iostream>
# include <vector>

using namespace std;
class Animal
{
public:
virtual void eat() const { cout << "I eat like a generic Animal." << endl; }
virtual ~Animal() {}
};

class Wolf : public Animal
{
public:
void eat() const { cout << "I eat like a wolf!" << endl; }
};

class Fish : public Animal
{
public:
void eat() const { cout << "I eat like a fish!" << endl; }
};

class GoldFish : public Fish
{
public:
void eat() const { cout << "I eat like a goldfish!" << endl; }
};


class OtherAnimal : public Animal
{
};

int main()
{
std::vector<Animal*> animals;
animals.push_back( new Animal() );
animals.push_back( new Wolf() );
animals.push_back( new Fish() );
animals.push_back( new GoldFish() );
animals.push_back( new OtherAnimal() );

for( std::vector<Animal*>::const_iterator it = animals.begin();
it != animals.end(); ++it)
{
(*it)->eat();
delete *it;
}

return 0;
}

以下是虚函数 Animal::eat() 的输出:

1
2
3
4
5
I eat like a generic Animal.
I eat like a wolf!
I eat like a fish!
I eat like a goldfish!
I eat like a generic Animal.

纯虚函数示例

在C++语言中, 纯虚函数用一种特别的语法[=0]定义。

1
2
3
4
class Abstract {
public:
virtual void pure_virtual() = 0;
};

纯虚函数的定义仅提供方法的原型. 虽然在抽象类中通常不提供纯虚函数的实现, 但是抽象类中可以包含其实现, 而且可以不在声明的同时给出定义[2]. 每个非抽象子类仍然需要重载该方法, 抽象类中实现的调用可以采用以下这种形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
void Abstract::pure_virtual() {
// do something
}

class Child : public Abstract {
virtual void pure_virtual(); // no longer abstract, this class may be
// instantiated.
};

void Child::pure_virtual() {
Abstract::pure_virtual(); // the implementation in the abstract class
// is executed
}

参考链接

  1. 虚函数和纯虚函数的区别,by hackbuteer1.
  2. 虚函数,by wikipedia.
  3. C++中虚析构函数的作用,by StarLee.
  4. 开源免费的C/C++网络库(c/c++ sockets library) 七剑下天山,by 工程师WWW.
  5. VS2010中属性页中,C/C++ –>预处理器定义,by J.M.Liu.
  6. 深入理解C/C++混合编程(关于#ifdef __cplusplus extern “C” {…}的用法),by zzwdkxx.
  7. 带你玩转 Visual Studio——带你多工程开发,by luoweifu.
  8. c++中冒号(:)和双冒号(::)的用法,by 小金乌会发光-Z&M.
  9. C++ 构造函数总结,by chaibubble.
  10. 详谈C++保护成员和保护继承,by C语言中文网.
  11. c++ 内联函数(一看就懂),by 兴趣斗士.
  12. 浅析C++类的内存布局,by 冯Jungle.
  13. 图说C++对象模型:对象内存布局详解,by melonstreet.
  14. C++ 对象的内存布局,by 陈皓.
  15. C++类对象的内存布局,by 一叶知秋dong.
  16. C++中类所占的内存大小以及成员函数的存储位置,by SOC罗三炮.
  17. struct的用法和struct的对齐原则,by 马小超i.