本篇讲述虚函数与纯虚函数的区别与用法
对于抽象类来说,它无法实例化对象,而对于抽象类的子类来说,只有把抽象类中的纯虚函数全部实现之后,那么这个子类才可以实例化对象
class person
{
private:
int age;
bool gender;
public:
void work();
void printInfo();
};
简单理解就是父类定义了一个群体将会有的动作以及行为:如Worker类,我们仅知道工人们会工作,但是我们不知道具体是什么工人以及从事于什么样的工作,因此,可以把worker类定义为抽象类,用以规定可能会有的行为以及操作。
class worker:public person
{
private:
int age;
bool gender;
public:
//定义为抽象基类是避免实例化造成的编译报错,并且基类的定义时1为了规定大致的行为操作,具体的内容实现是基于继承类
virtual void work() = 0;
virtual void printInfo() = 0;
};
同时,对于抽象类的子类也可以是抽象类,
class dustMan:public worker
{
private:
int age;
bool gender;
public:
//定义为抽象基类是避免实例化造成的编译报错,并且基类的定义时1为了规定大致的行为操作,具体的内容实现是基于继承类
virtual void work(){cout << "扫地";}
virtual void printInfo(){cout << "我是清洁工";}
};
需要注意的是,如果基类中有纯虚函数(该类为抽象类,不能实例化对象),那么子类实现过程中必须重新定义纯虚函数,编译器才不会报错。
-
虚函数是动态绑定的,也就是说。使用虚函数的指针和引用能够正确找到实际类的相应函数,而不是运行定义类的函数。
这是虚函数的基本功能,就不再解释了。
-
构造函数不能是虚函数。并且,在构造函数中调用虚函数,实际运行的是父类的相应函数。由于自己还没有构造好, 多态是被
disable
的。 -
析构函数能够是虚函数。并且,在一个复杂类结构中。这往往是必须的。
-
将一个函数定义为纯虚函数。实际上是将这个类定义为抽象类,不能实例化对象。
-
纯虚函数通常未定义体,但也全然能够拥有, 甚至能够显示调用。
-
析构函数能够是纯虚的,但纯虚析构函数必须有定义体,*由于析构函数的调用是在子类中隐含的*。
-
非纯的虚函数必须有定义体,不然是一个错误。
-
派生类的
override
虚函数定义必须和父类全然一致(c++11
中使用override
进行编译器检查)。除了一个特例,假设父类中返回值是一个指针或引用。子类override
时能够返回这个指针(或引用)的派生。比如,在上面的样例中,在
Base
中定义了virtual Base* clone()
; 在Derived
中能够定义为virtual Derived* clone()
。