我们根据一个例子来学习 virtual 函数=0 的知识
重要补充: 类中包含纯虚函数,这个类就不能实例化(初始化) 例如 Animal类有纯虚函数
Animal a; 这样是错误的
error: cannot declare variable ‘animal’ to be of abstract type ‘Animal’
如果学过c# java 都会知道 它们有 abstract 的概念, c++也是面向对象语言,也不例外也有这样的概念,表现形式却跟java 不一样
抽象类中不一定要包含abstract方法,但一个类中包含了abstract方法,则这个类必须声明为abstract类。
抽象类的实现子类必须实现抽象类中所有的abstract方法
抽象类中的函数分为 虚函数,普通函数,纯虚函数, 虚函数和普通成员函数 都必须要在基类中实现,如果不实现会造成编译错误.
编译器发现一个类中有被声明为virtual的函数,就会为其搞一个虚函数表,也就是VTABLE。VTABLE实际上是一个函数指针的数组,每个虚函数占用这个数组的一个slot。一个类只有一个VTABLE,不管它有多少个实例。派生类有自己的VTABLE,但是派生类的VTABLE与基类的VTABLE有相同的函数排列顺序,同名的虚函数被放在两个数组的相同位置上。在创建类实例的时候,编译器还会在每个实例的内存布局中增加一个vptr字段,该字段指向本类的VTABLE。
如果是虚函数 未实现,会出现如下错如
src\Animal.o:Animal.cpp:(.rdata$_ZTV6Animal[vtable for Animal]+0×10): undefined reference to `Animal::hello()’
其中提到 vtable for Animal
就是说,如果 new 子类的时候 , 父类没有实现virtual 函数, 就会说undefined reference ,
当使用
基类* p = new 子类
p->会调用基类的虚函数,就会出现上述错误,不过这个错误是在 编译时检查出来的。
看例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 /*
* Animal.h
*
* Created on: 2011-6-10
* Author: Administrator
*/
#ifndef ANIMAL_H_
#define ANIMAL_H_
class Animal {
public:
Animal();
virtual ~Animal();
virtual void hello() = 0;
};
#endif /* ANIMAL_H_ */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 /*
* Animal.cpp
*
* Created on: 2011-6-10
* Author: Administrator
*/
#include "Animal.h"
Animal::Animal() {
// TODO Auto-generated constructor stub
}
Animal::~Animal() {
// TODO Auto-generated destructor stub
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 /*
* Dog.h
*
* Created on: 2011-6-10
* Author: Administrator
*/
#ifndef DOG_H_
#define DOG_H_
#include "Animal.h"
class Dog: public Animal {
public:
Dog();
virtual ~Dog();
virtual void hello();
};
#endif /* DOG_H_ */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 /*
* Dog.cpp
*
* Created on: 2011-6-10
* Author: Administrator
*/
#include <iostream>
#include "Dog.h"
Dog::Dog() {
// TODO Auto-generated constructor stub
}
Dog::~Dog() {
// TODO Auto-generated destructor stub
}
void Dog::hello(){
std::cout <<"Dog::hello()"<<std::endl;
}
测试 main函数
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <iostream>
#include "Animal.h"
#include "Dog.h"
using namespace std;
int main() {
Dog *g = new Dog();
Animal *a = g;
g->hello();
a->hello();//Animal class调用的也是Dog的virtual函数
delete g;
return 0;
}
联系客服