Morisummer.. 2023-01-14 20:33 采纳率: 85.2%
浏览 50
已结题

C++为什么释放内存后还能访问

img

img


/*
运行阶段类型识别,为程序在运行阶段确定对象的类型,只适用于包含虚函数的类
问题引入:基类指针可以指向派生类对象,如何知道基类指针指向的是那个派生类的对象呢?
dynamic_cast运算符使用指向基类的指针来生成派生类指针,它不能回答“指针指向的是什么类的对象”,但能回答“是否可以安全的将对象的地址赋值给特定类型的指针”
这个问题
重点复习:free 和 delete可以一起释放掉后面的连续空间
*/

//以下为虚函数复习,dynamic_cast

#include <iostream>
using namespace std;

class Hero
{
public:
    virtual void skill1()
    {
        cout << "英雄释放了1技能" << endl;
    }
    
    virtual void skill2()
    {
        cout << "英雄释放了2技能" << endl;
    }

    virtual void skill3()
    {
        cout << "英雄释放了3技能" << endl;
    }
};

class XS : public Hero
{
public:
    virtual void skill1()
    {
        cout << "西施释放了1技能" << endl;
    }

    virtual void skill2()
    {
        cout << "西施释放了2技能" << endl;
    }

    virtual void skill3()
    {
        cout << "西施释放了3技能" << endl;
    }

    void skill4()
    {
        cout << "西施释放了4技能" << endl;
    }
};

class LB : public Hero
{
public:
    virtual void skill1()
    {
        cout << "李白释放了1技能" << endl;
    }

    virtual void skill2()
    {
        cout << "李白释放了2技能" << endl;
    }

    virtual void skill3()
    {
        cout << "李白释放了3技能" << endl;
    }
};

class HZ : public Hero
{
public:
    virtual void skill1()
    {
        cout << "猴子释放了1技能" << endl;
    }

    virtual void skill2()
    {
        cout << "猴子释放了2技能" << endl;
    }

    virtual void skill3()
    {
        cout << "猴子释放了3技能" << endl;
    }
};

int main()
{
    Hero* ptr = nullptr;
    int id;
    cin >> id;
    switch (id)
    {
    case 1:
        ptr = new XS;
        break;
    case 2:
        ptr = new LB;
        break;
    case 3:
        ptr = new HZ;
        break;
    default:
        ptr = new Hero;
        break;
    }
    ptr->skill1();
    ptr->skill2();
    ptr->skill3();

    if (id == 1)
    {
        XS* xsptr = dynamic_cast<XS*>(ptr);
        xsptr->skill4();
        delete xsptr;
        //为什么这里释放掉xsptr后还能调用skill4
        xsptr->skill4();
    }
    return 0;
}
  • 写回答

3条回答 默认 最新

  • 关注

    应该叫C++为什么释放对象内存后还能访问类成员函数.
    *
    因为你的对象内存中只存储一个虚函数表指针, 如果有成员对象则还会存储成员对象.
    *
    delete只是释放虚函数表指针和成员对象, 所以调用成员对象或虚函数会报错, 但delete没有清除类本身的实现, 所以哪怕指向nullptr的类指针也能调用类成员函数. 当然, 如果这个类成员函数调用类成员对象一样会报错.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月29日
  • 已采纳回答 1月29日
  • 创建了问题 1月14日

悬赏问题

  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥15 键盘指令混乱情况下的启动盘系统重装