博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++多态与虚函数
阅读量:7121 次
发布时间:2019-06-28

本文共 2053 字,大约阅读时间需要 6 分钟。

1、虚函数 virtual

虚函数可以参与多态,而普通函数不能。

class base {    virtual int get() ;};int base::get(){ }

Note:

virtual关键字只用在类定义的函数声明里,写函数体时不用。

构造函数和静态成员函数不能是虚函数。

2、多态:增强程序可扩充性

(1)派生类的指针可以赋给基类指针

通过基类指针调用基类和派生类中的同名虚函数时:

若该指针指向一个基类的对象,那么被调用是基类的虚函数;

若该指针指向一个派生类的对象,那么被调用的是派生类的虚函数。

(2)派生类的对象可以赋给基类引用

通过基类引用调用基类和派生类中的同名虚函数时:

若该引用引用的是一个基类的对象,那么被调用是基类的虚函数;

若该引用引用的是一个派生类的对象,那么被调用的是派生类的虚函数。

Note:用基类指针数组存放指向各种派生类对象的指针,然后遍历该数组,就能对各个派生类对象做各种操作,是很常用的做法。

注意,Attention!见下面程序:

class Base {public:    void fun1() { fun2(); }    virtual void fun2() { cout << "Base::fun2()" << endl; }};class Derived:public Base {public:    virtual void fun2() { cout << "Derived:fun2()" << endl; }};int main() {    Derived d;    Base * pBase = & d;    pBase->fun1();    return 0;}

输出

Derived:fun2()

原因在非构造函数,非析构函数的成员 函数中调用虚函数,是多态!!!

class Base {public:    void fun1() { this->fun2(); } //this是基类指针,fun2是虚函数,所以是多态    virtual void fun2() { cout << "Base::fun2()" << endl; }};class Derived:public Base {public:    virtual void fun2() { cout << "Derived:fun2()" << endl; }};int main() {    Derived d;    Base * pBase = & d;    pBase->fun1();    return 0;}

在构造函数和析构函数中调用虚函数,不是多态。

在派生类中和基类中虚函数同名同参数表的函数,不加virtual也自动成为虚函数。

3、多态实现的关键:虚函数表

每个对象虚函数表的存放以及虚函数表的查询过程会分别增加程序的空间开销和时间开销。

4、虚析构函数

class CSon{ public: ~CSon() { };};class CGrandson : CSon{ public: ~CGrandson() { }; }int main(){ CSon *p = new CGrandson; delete p; return 0;  

在delete p时只调用了基类的析构函数,没有调用派生类的析构函数,可能造成内存空间无法回收。

解决方法:把基类的析构函数声明为virtual

• 派生类的析构函数 virtual可以不进行声明

• 通过基类的指针删除派生类对象时,首先调用派生类的析构函数,然后调用基类的析构函数

Note:类如果定义了虚函数, 则最好将析构函数也定义成虚函数。注意,不允许以虚函数作为构造函数。

class son{public:    virtual ~son() { cout<<"bye from son"<

5、抽象类

(1)纯虚函数:没有函数体的虚函数。

class A {private:    int a;public:    virtual void Print( ) = 0 ; //纯虚函数    void fun() { cout << “fun”; }};

(2)抽象类:包含纯虚函数的类。

只能作为积累来派生新类使用;不能创建抽象类的对象;抽象类的指针和引用可以指向由抽象类派生出来的类的对象。

A a; // 错, A 是抽象类, 不能创建对象A * pa; // ok, 可以定义抽象类的指针和引用pa = new A; //错误, A 是抽象类, 不能创建对象 

抽象类中,成员函数可以调用纯虚函数,但构造函数/析构函数内部不能调用纯虚函数。

如果一个类从抽象类派生而来,它必须实现基类中的所有纯虚函数,才能成为非抽象类。

转载于:https://www.cnblogs.com/zhuzhudong/p/10841440.html

你可能感兴趣的文章
php count()函数用法 及其 一个坑
查看>>
Qt可扩展窗口实现
查看>>
JS自学笔记04
查看>>
MySQL基础
查看>>
写操作系统学到
查看>>
真正统治世界的十大算法
查看>>
FZU-2236 第十四个目标(树状数组)
查看>>
hibernate多表关联(<hibernate-mapping>)的配置
查看>>
07 Django 模板
查看>>
Redis的简介、启动、停止
查看>>
Jmeter性能测试 入门
查看>>
CSS_圣杯
查看>>
宜信敏捷数据中台建设实践|分享实录
查看>>
如何抓准问题?
查看>>
Office 365 On MacOS 系列——配置浏览器账号同时管理多个订阅
查看>>
先考学历还是先提升能力?
查看>>
openstack云计算实践-老男孩架构师课程教案笔记分享
查看>>
大规模网站sesson会话保持思路及实践配置
查看>>
python glob模块的应用
查看>>
从0到1简易区块链开发手册V0.6-实现打印区块
查看>>