栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

(C++)多态

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

(C++)多态

目录

一、多态的概念

1、问题的引出

2、多态的概念

3、多态的原理

4、虚析构函数

二、动态类型识别

1、问题的引出

2、dynamic_cast关键字用法

3、typeid关键字

三、纯虚函数


一、多态的概念

1、问题的引出

基类的指针指向派生类对象,在访问函数(基类与派生类的同名函数)时,只能调用基类的函数。

如何才能通过基类指针调用派生类函数?

#include 
using namespace std;
class Parent
{
    public:
        void show()
        {
            cout<<"this is Parent"<show();  //静态联编,编译器根据p1的类型(parent *)调用Parent里面的show函数
    return 0;    //却不能按我们期望的那样,调用派生类函数
}

2、多态的概念

在基类指针指向基类对象的时候,按照基类的方法做事,在指向派生类对象的时候,就按照派生类对象的方法做事,换句话说,基类指针可以根据指向的不同,既可以按照基类的方法做事 也可以按照派生类方式做事,它有多种形态,或者多种表现方式,这种现象称之为多态。

多态产生的条件:

1.要有继承

2.要有虚函数重写(发生在不同的作用域中,函数原型相同)

3.基类指针指向派生类对象

#include 
using namespace std;
class Parent
{
    public:
        virtual void show()    //被virtual修饰的函数称为虚函数
        {
            cout<<"this is Parent"<show();  //动态联编:运行的时候才知道p1指向什么对象


    delete p1;
    p1 = new Parent;
    p1->show();


    
    return 0;
}

3、多态的原理

#include 
using namespace std;
class Parent
{
    public:
        int a;
        virtual void show()    //被virtual修饰的函数称为虚函数
        {
            cout<<"this is Parent"<show();  //通过指针找到对象,通过对下个前8个字节找到虚函数表,
                 //通过虚函数表来找对应的函数(效率低),不要将所有的函数都声明为虚函数
    return 0;
}

4、虚析构函数

根据析构的规则,只能从当前基类往上调用析构函数,并不能调用子类的析构函数,通过将基类中的析构函数声明为虚析构,使得其能按照正确的顺序进行动态的释放对象。

#include 
using namespace std;
class Parent
{
    public:
        int a;
    Parent()
    {
        cout<<" Parent的构造函数"<show();
    delete p;
    return 0;
}

二、动态类型识别 1、问题的引出

(1)新的关键词:dynamic_cast

(2)dynamic_cast用于基类和派生类之间的转换

(3)dynamic_cast要求使用的目标类型是多态的

        所以说: 要求至少有一个虚函数

                     用于指针转换时,转换失败返回NULL指针

                     用于引用转换时,转换失败引发bad_cast异常

#include 
using namespace std;
class Parent
{
    private:
        int a;
    public:
        enum {ID = 0};
        virtual int GetID()
        {
            return ID;
        }
};

class Child:public Parent
{
    public:
        enum {ID = 1};
        virtual int GetID()
        {
            return ID;
        }
};

void f(Parent *p)
{
    if(p->GetID() == Child::ID)  //如果成立,说明指向派生类对象,没有任何转化过程
    {
        Child *c = (Child *)p;    //进一步将p指针转化为c型指针
        cout<<"可以转换"< 

2、dynamic_cast关键字用法

该关键字主要用于基类与派生类之间的类型转换。

#include 
using namespace std;

class Parent
{
    private:
        int a;
    public:
        virtual void show(){};
};

class Child:public Parent
{
    public:
        enum {ID = 1};
        virtual void show(){};
};

void f(Parent *p)
{
    Child *c = dynamic_cast(p);   //可用dynamic_cast直接转换类型
    if(NULL == c)  //转换失败,会返回NULL
    {
        cout<<"转换失败"< 

3、typeid关键字

typeid运算符用来获取一个表达式的类型信息

typeid的操作对象可以是表达式,也可以是数据类型

typeid(expression) 或者 typeid(datatype)

#include 
#include 
using namespace std;

class Parent
{
    private:
        int a;
    public:
        virtual void show(){};
};

class Child:public Parent
{
    public:
        enum {ID = 1};
        virtual void show(){};
};

void f(Parent *p)
{
    if(typeid(*p) == typeid(Child))   //说明指针p指向Child。可以进行类型转换
    {
        cout<<"转换成功"< 

三、纯虚函数

格式:virtual 返回值类型  函数名  (函数参数) = 0;

含有纯虚函数的类称为抽象类,抽象类不能定义实例对象。

#include 
using namespace std;

class Parent 
{
    private:
        int a;
    public:
        virtual void show() = 0;    //纯虚函数,没有函数体
};

class Child:public Parent
{
    public:
        virtual void show()
        {
            cout<<"this is child!"<show();
    
    return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/928102.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号