基类指针指向派生类,派生类指针指向基类(个人笔记)

A作为基类,B作为派生类:

基类指针指向派生类(对象):

在c++中,基类的析构函数需要定义为虚函数,原因有以下几点:

当使用多态特性,让基类指针指向派生类时(不是指向 B people 定义来的people这种对象详细看下文代码),如果析构函数不是虚函数,通过基类指针销毁派生类对象时(delete pa),会调用静态绑定的析构函数,也就是基类的析构函数,从而只能销毁属于基类的元素,导致派生类析构不完全,程序就会出现资源泄露或未定义行为。

不加virtual的基类析构函数:

class A
{
    public:
        virtual void Play()
        {;}
        A()
        {
            cout<<"构造A"<<endl;
        }

        ~A()
        {
            cout<<"A析构"<<endl;
        }
    
    
};

class B : public A
{
    public:
        void Play()
        {
            cout<<"B"<<endl;
        }
        B()
        {
            cout<<"构造B"<<endl;
        }
        ~B()
        {
            cout<<"B析构"<<endl;
        }
    
    
};

这里的结果证明派生类没有析构,也就是说如果此时B类中有动态空间成员内存将不会被释放。

将基类析构函数设置为虚函数之后就是这样的:

但是你不将基类析构函数设置为虚函数,通过具体对象自动析构也不会出现问题,只有你通过基类指针删除才会出现问题:

运行结果:

派生类指针指向基类对象:

注:从pa=&b,这里可看出,解释一下:这里取得是b的首地址,而pa的长度是由数据类型的内存所占大小决定的,也就是A类的大小;

pb=&a的话是会报错的,因为pb的长度(下方红色箭头范围)已经超出了A(上方红色箭头范围)的内存范围,多出的那一部分可能会乱指,导致安全性缺失

pb是派生类指针,pb本身的大小在定义时(B *pb)已经决定了它就比A类的具体对象"a"大,所以如果用派生类指针pb指向基类的"a"会导致pb空出一部分空间没有指向(指针必须有所指向),导致上文说的“安全性缺失”。

总结:派生类指针不能指向基类对象。

附录:

基类指针指向派生类(对象)B类中有动态空间成员的情况:

#include <iostream>
#include <cstring>

using namespace std;

class A
{
    public:
        virtual void Play()
        {;}
        A()
        {
            cout<<"构造A"<<endl;
        }

        ~A()
        {
            cout<<"A析构"<<endl;
        }
    
    
};

class B : public A
{
	
    public:
    char *pname;
        B(char *a)
        {
            pname = new char(strlen(a)+1);
            strcpy(pname,a);
            cout<<"构造B"<<endl;
        }
        ~B()
        {
            delete pname;
            cout<<"B析构"<<endl;
        }
        void Play()
        {
            cout<<pname<<endl;
        }
    
};

int main()
{
    A *pa = new B("zhangsan");
    pa->Play();
    delete pa;
}

运行结果:

B的pname内存没有释放。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值