C++基础-虚函数/纯虚函数/普通函数
2017-09-28 18:51
435 查看
序言
本文主要内容:虚函数 + 纯虚函数 + 普通函数 + 虚函数纯虚函数的区别1. 虚函数
什么是虚函数被virtual关键字修饰的成员函数,就是虚函数
为什么要使用虚函数
引入虚函数主要为了实现重写和多态
虚函数主要作用是为了实现“动态多态性”,父类提供虚函数的实现,为子类提供默认的函数实现。子类可以重写父类的虚函数实现子类的特殊化。
说明
对于虚函数来说,父类和子类都有各自的版本,由多态方式调用的时候动态绑定。
虚函数必须实现,否则在链接时将会报错
2. 纯虚函数
什么是纯虚函数virtual returnType function() = 0;
为什么要使用纯虚函数
也是为了实现“动态多态性”
在很多情况下,基类本身生成对象是不合情理的,动物基类可以派生出老虎、孔雀等,但是动物本身的对象却没有实际意义,所以引入了纯虚函数
什么情况下使用纯虚函数
在基类中抽象出一个方法,且该基类只能被继承不能被实例化。
这个方法必须在派生类中被实现。
满足以上两点,可考虑声明为纯虚函数。
3. 普通函数
类的普通成员函数。父类为子类提供了普通函数的强制实现
普通函数是静态编译的,可类内重载但没有运行时多态,只会根据指针或引用的“字面值”类对象,调用自己的普通函数。
4. 虚函数和纯虚函数举例
[1] 普通函数举例(静态联编)/* 例1 */ class A { public: void funPrint() { cout<<"function in class A"<<endl; } }; class B:public A { public: void funPrint() //重定义 { cout<<"function in class B"<<endl; } }; int main() { A *p; //基类指针 A a; //基类对象 B b; //派生类对象 p = &a; p->funPrint(); p = &b; p->funPrint(); b.funPrint(); b.A::funPrint(); return 0; } //输出结果: function in class A function in class A function in class B function in class A //原因: (1)静态联编:编译器在编译时就确定好了函数调用 (2)只是普通函数“重定义”,不管引用的实例是哪个类的,调用的时候系统会调用 “左值” 那个对象所属类的方法 >>> 所以基类A指针p最终调用类A的funPrint()函数,输出两个function in class A >>> 类B实例调用类B的funPrint()函数,类B加上作用域操作符A::调用类A的funPrint()函数 /* 例2 */ #include <iostream> using namespace std; class A { public: virtual void fun1() = 0; //纯虚函数 virtual ~A(){}; virtual void fun2() //虚函数 { cout<<"fun1 in class A"<<endl; } void fun3() //普通成员函数 { cout<<"fun3 in class A"<<endl; } }; class B:public A { public: virtual ~B(){}; void fun1() //纯虚函数实现 { cout<<"fun1 in class B"<<endl; } void fun2() //虚函数重写(覆盖) { cout<<"fun2 in class B"<<endl; } void fun3() //普通函数重定义 { cout<<"fun3 in class B"<<endl; } }; int main() { A *a = new B; //抽象类定义指针 a->fun1(); a->fun2(); a->fun3(); cout<<"*******************"<<endl; B b; //派生类实例化 b.fun1(); b.fun2(); b.fun3(); delete a; //释放 new 的对象 return 0; } //输出结果: fun1 in class B //纯虚函数在基类中声明在子类中实现 fun2 in class B //动态联编:多态。虚函数在子类中重写,运行时动态绑定 fun3 in class A //静态联编:编译时就确定好了调用哪个函数。调用左值所属类的方法 ******************* fun1 in class B fun2 in class B //动态联编:多态。虚函数在子类中重写,运行时动态绑定 fun3 in class B //静态联编:调用左值所属类的方法
[2] 虚函数举例(动态联编)
class A { public: virtual void funPrint() { cout<<"function in class A"<<endl; } }; class B:public A { public: void funPrint() //或virtual void funPrint(),重写 { cout<<"function in class B"<<endl; } }; int main() { A *p; //基类的指针 A a; B b; p = &a; p->funPrint(); p = &b; p->funPrint(); return 0; } //输出结果: function in class A function in class B //原因: (1)动态联编:根据实例的不同动态决定调用哪个函数 (2)虚函数的唯一目的就是为了实现多态(动态多态性),编译时不确定调用哪个函数,而是动态的决定要调用哪个函数,即“运行时多态” >>> 所以基类A指针p指向类A的实例a就调用类A的funPrint()函数, >>> 指向类B的实例b就调用类B的funPrint()函数
[3] 纯虚函数举例(抽象类)
纯虚函数通常存在于抽象类中,在基类中只是声明一个函数但不去实现它,让派生类去实现
class Vehicle { public: virtual void PrintTyre() = 0; //纯虚函数 }; class Car:public Vehicle { public: virtual void PrintTyre() { cout<<"Car tyre four"<<endl; } }; class Bike:public Vehicle { public: virtual void PrintTyre() { cout<<"Bike tyre two"<<endl; } }; int main() { Car c; Bike b; b.PrintTyre(); c.PrintTyre(); return 0; } //输出结果: Car tyre four Bike tyre two //原因: (1)定义vehicle类,但是具体每种交通工具有多少个轮子是不一定的,就定义为纯虚函数、留待派生类中具体实现
5. 虚函数和纯虚函数的联系与区别
联系虚函数和纯虚函数可以定义在同一个类中
虚函数和纯虚函数都可以在子类中被重写,以多态的形式调用
虚函数和纯虚函数通常存在于抽象基类中,被子类继承,目的是提供一个统一的接口
虚函数和纯虚函数的定义中不能有static标识符,因为static要求编译时即绑定,而虚函数和纯虚函数运行时才绑定(动态多态性)
实现了纯虚函数的子类,该纯虚函数在子类中就变成了虚函数,子类的子类即孙子类可以覆盖(重写)该虚函数,由多态方式调用的时候动态绑定
区别
定义:
虚函数virtual returnType function();
纯虚函数virtual returnType function() = 0;
抽象类:
含有纯虚函数的类称为抽象类,而只含有虚函数的类不能称为抽象类
抽象类不能实例化,但可以定义抽象类的指针和引用(见例2)
使用:
虚函数可以直接使用,也可以子类重写后以多态形式调用
虚函数在基类中只有声明没有定义,是对子类的约束,是“接口继承”,必须在子类中实现该函数才可以使用
Acknowledgements:
http://www.cnblogs.com/xudong-bupt/p/3570304.html
http://www.cnblogs.com/fzhe/archive/2013/01/02/2842513.html
http://blog.chinaunix.net/uid-26851094-id-3327323.html
http://www.cnblogs.com/crazyacking/p/5265634.html(推荐)
http://www.cnblogs.com/bluestorm/archive/2012/08/29/2662350.html
2017.09.28
相关文章推荐
- c/c++ 基础(七) 函数覆盖,虚函数,纯虚函数对比
- c++ 普通函数 虚函数 纯虚函数 代码例子
- c++ 普通函数、虚函数、纯虚函数的区别
- C++之普通成员函数、虚函数以及纯虚函数的区别与用法要点
- c++对于虚函数,纯虚函数,普通函数的理解
- C++之普通成员函数、虚函数以及纯虚函数的区别与用法要点
- 【C++】普通函数、虚函数和纯虚函数
- C++之普通成员函数、虚函数以及纯虚函数的区别与用法要点
- 普通函数、虚函数、纯虚函数、
- 纯虚函数、虚函数、普通成员函数的知识点
- C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
- C++普通重载,虚函数重载,纯虚函数重载
- C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
- C++中virtual(虚函数)和普通函数调用的不同
- 虚函数、纯虚函数、普通函数的区别
- C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
- C++ 函数, 虚函数, 纯虚函数
- C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
- C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别
- C++实例之虚函数(析构函数和普通函数)