C++虚函数与纯虚函数
2016-06-30 11:01
267 查看
C++中虚函数与纯虚函数都是为了实现多态性而引入的,这里谈谈自己对虚函数与纯虚函数的一点理解。
在基类中将某函数声明为虚函数或者纯虚函数后,则子类中该函数自动成为虚函数。
虚函数必须在基类中实现,这样子类中可以实现,也可以不用实现该函数,根据实际需要。
纯虚函数在基类中可以实现,也可以不实现,子类中必须有实现。实际上纯虚函数在基类中的实现是没有意义的,因为含有纯虚函数的类是抽象类,抽象类是不能创建对象的,也就无法调用到该纯虚函数。当然,有的小伙伴可能会想将纯虚函数定义为静态的(即用static修饰),不就可以通过类名去调用了吗?其实不然,C++引入虚函数、纯虚函数的目的是为了实现运行时的多态性,这种多态性需要通过运行时this指针的移动去实现的,而静态成员函数属于类所有的,没有this指针。虚函数不能定义为静态的。
这里有个特殊的函数需要提一下,析构函数。
在基类中,一定要将析构函数声明为虚函数。因为我通常使用多态的方式是定义一个基类指针去指向子类的对象,正是由于虚函数的作用,程序运行时基类的指针会根据需要去调用子类相应的函数,若不将基类的析构函数声明为虚函数,则在子类对象被释放时,基类指针只会调用基类的析构函数,而不会去调用子类的析构函数。
本人语言表达水平有限,说的可能有点绕,上代码示例辅助理解。
在基类中将某函数声明为虚函数或者纯虚函数后,则子类中该函数自动成为虚函数。
虚函数必须在基类中实现,这样子类中可以实现,也可以不用实现该函数,根据实际需要。
纯虚函数在基类中可以实现,也可以不实现,子类中必须有实现。实际上纯虚函数在基类中的实现是没有意义的,因为含有纯虚函数的类是抽象类,抽象类是不能创建对象的,也就无法调用到该纯虚函数。当然,有的小伙伴可能会想将纯虚函数定义为静态的(即用static修饰),不就可以通过类名去调用了吗?其实不然,C++引入虚函数、纯虚函数的目的是为了实现运行时的多态性,这种多态性需要通过运行时this指针的移动去实现的,而静态成员函数属于类所有的,没有this指针。虚函数不能定义为静态的。
这里有个特殊的函数需要提一下,析构函数。
在基类中,一定要将析构函数声明为虚函数。因为我通常使用多态的方式是定义一个基类指针去指向子类的对象,正是由于虚函数的作用,程序运行时基类的指针会根据需要去调用子类相应的函数,若不将基类的析构函数声明为虚函数,则在子类对象被释放时,基类指针只会调用基类的析构函数,而不会去调用子类的析构函数。
本人语言表达水平有限,说的可能有点绕,上代码示例辅助理解。
#include <iostream> class Animal { public: //基类的析构函数必须声明为虚函数。 //若要将基类的析构函数声明为纯虚函数,则必须有实现,否则编译失败 virtual ~Animal() = 0; //这里作为示例,将析构函数声明为纯虚函数 Animal(){} public: virtual void Run() { std::cout << "Animal Run ..." << std::endl; } virtual void Speak() = 0; //普通函数声明为纯虚函数是可以不需要实现的(实际上实现也没意义) }; Animal::~Animal(){} //因为上面已将该析构函数声明为纯虚函数,这里必须有实现 void Animal::Speak() //该实现是没有意义的,建议不要去实现普通的纯虚函数 { std::cout << "Animal Speak ..." << std::endl; } class Cat: public Animal { public: Cat(){} ~Cat(){}; public: //这里Speak()函数必须有实现,Run()函数则可以继承基类 void Speak() { std::cout << "喵喵喵 ..." << std::endl; } }; int main() { Animal* aml = new Cat; aml->Run(); aml->Speak(); return 0; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- c#中虚函数的相关使用方法
- C#与.net高级编程 C#的多态介绍
- C#中面向对象编程机制之多态学习笔记
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C#中的多态深入理解
- C#中多态、重载、重写区别分析
- 设计引导--一个鸭子游戏引发的设计理念(多态,继承,抽象,接口,策略者模式)
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题