c++多态

作者: arkliu | 来源:发表于2022-11-23 09:11 被阅读0次

多态的基本概念

  • 基类指针只能调用基类的成员函数,不能调用派生类的成员函数
#include <iostream>
#include<string>
using namespace std;

class Parent{
    public:
        int m_id = 0;
        void show() {
            cout <<"Parent::show() m_id:"<<m_id<<endl;
        }
};

class Child:public Parent {
    public:
        int m_age;
        void show() {
            cout <<"Child::show() m_id:"<<m_id << "   m_age:"<<m_age<<endl;
        }

};

int main() {
    Child ch;
    ch.m_id = 10;
    ch.m_age = 20;
    Parent *par = &ch;
    par->show(); // 基类指针指向派生类对象,调用基类的函数
    return 0;   
}

image.png
  • 如果在基类的成员函数前加上virtual关键字,把他声明为虚函数,基类指针就可
    以调用派生类的成员函数。
    \color{red}{在基类的show方法前加上virtual关键字,声明为虚函数}
class Parent{
    public:
        int m_id = 0;
        // 在基类的show方法前加上virtual关键字,声明为虚函数
        virtual void show() {
            cout <<"Parent::show() m_id:"<<m_id<<endl;
        }
};
image.png
  • 有了虚函数,基类指针指向基类对象就使用基类成员函数和基类的数据,指向派生类对象时,就使用派生类对象的成员函数,和派生类的数据
#include <iostream>
#include<string>
using namespace std;

class Parent{
    public:
        int m_id = 0;
        // 在基类的show方法前加上virtual关键字,声明为虚函数
        virtual void show() {
            cout <<"Parent::show() m_id:"<<m_id<<endl;
        }
};

class Child:public Parent {
    public:
        int m_age;
        void show() {
            cout <<"Child::show() m_id:"<<m_id << "   m_age:"<<m_age<<endl;
        }

};

int main() {
    Child ch;
    ch.m_id = 10; ch.m_age = 20; //创建派生类对象并赋值
    Parent par;
    par.m_id = 33;
    
    Parent *ppar = &ch;
    ppar->show(); // Child::show() m_id:10   m_age:20
    ppar = &par;
    ppar->show(); // Parent::show() m_id:33
    return 0;   
}
image.png

\color{red}{注意:}

  • 只需要在基类的函数声明中加上virtual关键字,函数定义时不能加。
class Parent{
    public:
        int m_id = 0;
        // 在基类的show方法前加上virtual关键字,声明为虚函数
        virtual void show();
};

void Parent::show() {
    cout <<"Parent::show() m_id:"<<m_id<<endl;
}
  • 当在基类中定义类虚函数时候,如果派生类没有定义该函数,那么将使用基类的虚函数。
  • 在派生类中重定义了虚函数的情况下,如果要使用基类的函数,可以加类名和域解析符。
Child ch;
ch.m_id = 10; ch.m_age = 20; //创建派生类对象并赋值
Parent par;
par.m_id = 33;

Parent *ppar = &ch;
ppar->Parent::show(); // Parent::show() m_id:33
image.png

虚析构函数

有时会让一个基类指针指向用 new 运算符动态生成的派生类对象;同时,用 new 运算符动态生成的对象都是通过 delete 指向它的指针来释放的。如果一个基类指针指向用 new 运算符动态生成的派生类对象,而释放该对象时是通过释放该基类指针来完成的,就会导致少释放一次, 看下面案例:

virtual_deconstruct.h

#pragma once
#include <iostream>
using namespace std;

class Parent
{
private:
public:
    Parent();
    ~Parent();
};

Parent::Parent()
{
    cout << "Parent() runs.." << endl;
}

Parent::~Parent()
{
    cout << "~Parent() runs.." << endl;
}

class Child : public Parent
{
private:
public:
    Child();
    ~Child();
};

Child::Child()
{
    cout << "Child() runs.." << endl;
}

Child::~Child()
{
    cout << "~Child() runs.." << endl;
}

测试代码

#include <iostream>
#include "virtual_deconstruct.h"

using namespace std;

int main() {
    Parent * p = new Child();

    delete p;
    return 0;
}
image.png

输出结果说明,\color{red}{delete p;只引发了 Parent类的析构函数被调用},没有引发 Child类的析构函数被调用。这是因为该语句是静态联编的,编译器编译到此时,不可能知道此时 p 到底指向哪个类型的对象,它只根据 p 的类型是 Parent* 来决定应该调用 Parent类的析构函数。

按理说,delete p;会导致一个 Child类的对象消亡,应该调用 Child类的析构函数才符合逻辑,否则有可能引发程序的问题

解决
更改改写上面程序中的 Parent类,在析构函数前加 virtual 关键字,将其声明为虚函数:

class Parent
{
private:
public:
    Parent();
    virtual ~Parent();
};

此时运行结果如下:


image.png

相关文章

  • 深刻剖析之c++博客文章

    三大特性 封装、继承、多态 多态 C++ 虚函数表解析C++多态的实现原理 介绍了类的多态(虚函数和动态/迟绑定)...

  • 多态的C++实现

    多态的C++实现 1 多态的原理 什么是多态?多态是面向对象的特性之一,只用父类指针指向子类的对象。 1.1 多态...

  • C++ 的多态(Polymorphism), virtual f

    多态 c++支持两种多态,编译时多态和运行时多态但其实编译时多态根本不是真正的多态,编译时多态就是函数的重载,ov...

  • C++第六篇多态

    C++中的多态性分为编译时多态性和运行时多态性,编译时多态通过函数重载和模板体现,运行多态通过虚函数体现编译、连接...

  • 面试题目收集总结

    C++: 多态: 多态性都有哪些?(静态和动态,然后分别叙述了一下虚函数和函数重载) c语言和c++有什么区别?(...

  • C++的多态

    C++三大特性:封装、继承和多态。其中最好理解的就是封装了,继承作为C++面向对象的特征也不难理解,那么多态,应该...

  • 实现golang语言的多态

    如何实现golang语言的多态? C++里面有多态是其三大特性之一,那么golang里面的多态我们该怎么实现? g...

  • Swift 多态实现探究

    多态 父类指针指向子类对象 Swift 中多态的实现类似于 c++ 中的虚表 OC 多态实现利用的是 Runtim...

  • C++编译期多态和运行期多态

    C++多态有多种实现方式,在面对对象编程时,采用的是运行期多态,也称动态多态。在泛型编程中,多态基于模板的具现化与...

  • c++多态

    什么是多态性? 多态:相同对象收到不同消息或不同对象收到相同消息时产生不同的动作。C++支持两种多态性:编译时多态...

网友评论

      本文标题:c++多态

      本文链接:https://www.haomeiwen.com/subject/fhostdtx.html