55-经典问题分析四

1、问题1-动态内存分配

这里写图片描述

2、new malloc区别

这里写图片描述

3、

这里写图片描述
Test::Test()
new Test在堆空间申请了一段内存并初始化了一个Test对象(并调用构造函数)
而malloc不会对内存进行初始化,仅仅是申请了一段内存

4、

这里写图片描述

5、

这里写图片描述
Test::Test()
~Test::Test()
成功创建 Test对象,调用构造函数
delete 释放pn的内存空间,而内存空间中存放的是对象,会触发对象的析构函数摧毁对象

    Test* pn = new Test;
    Test* pm = (Test*)malloc(sizeof(Test));

    free(pn);
    free(pm);
输出
Test::Test()
因为free只释放pn指向的内存,而内存当中存的是对象,无法调用对象的析构函数摧毁对象,结果会造成内存泄露
#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

class Test
{
    int* mp;
public:
    Test()
    {
        cout << "Test::Test()" << endl;

        mp = new int(100);

        cout << *mp << endl;
    }
    ~Test()
    {
        delete mp;

        cout << "~Test::Test()" << endl;
    }
};

int main()
{
    Test* pn = new Test;
    Test* pm = (Test*)malloc(sizeof(Test));

    delete pn;
    free(pm);

    return 0;
}
Test::Test()
100
~Test::Test()
6、delete fiee 区别

这里写图片描述

7、虚函数问题

这里写图片描述

8、

这里写图片描述
构造函数设置成虚函数后,编辑器会报错,不能将构造函数设置为虚函数
虚函数表指针实在构造函数执行后才被正确的初始化,构造函数是一个入口点,如果入口点都没有对象无法初始化

析构函数可以发生多态

8、析构函数未设置成虚函数,影响
#include <iostream>
#include <string>

using namespace std;

class Base
{
public:
    Base()
    {
        cout << "Base()" << endl;

    }

    ~Base()
    {

        cout << "~Base()" << endl;
    }
};


class Derived : public Base
{
public:
    Derived()
    {
        cout << "Derived()" << endl;
    }


    ~Derived()
    {
        cout << "~Derived()" << endl;
    }
};


int main()
{
    Base* p = new Derived();

    // ...

    delete p;

    return 0;
}
Base()
Derived()
~Base()

发现父类的析构函数位定义为虚函数:
首先父类指针指向一个 new 创建一个子类对象,子类对象在堆空间调用构造函数初始化,先调用父类构造函数,再调用子类初始化。
然后delete p释放堆空间的子类derived对象,首先点调用子类的析构函数,再调用父类的析构函数(期望的情况下是这样的)。
但实际上是只调用了父类的析构函数,而没有调用子类的析构函数,
原因:由于删除的指针类型是父类指针,会直接调用父类的析构函数(因为父类指针未定义成virtual虚函数类型,定义成虚函数后,就会
动态识别当前指针指向的对象类型来调用对应的析构函数,便会先调用子类对象的析构函数,然后调用父类的析构函数,跟多态原理一样)
虚析构函数:确保子类当中的动态分配内存操作在最终得以安全释放。
虚析构函数本质是实现多态





9、

这里写图片描述
不可以

10、

这里写图片描述

11、

这里写图片描述
编译器自己会进行选择

#include <iostream>
#include <string>

using namespace std;

class Base
{
public:
    Base()
    {
        cout << "Base()" << endl;

        func();
    }

    virtual void func() 
    {
        cout << "Base::func()" << endl;
    }

    virtual ~Base()
    {
        func();

        cout << "~Base()" << endl;
    }
};


class Derived : public Base
{
public:
    Derived()
    {
        cout << "Derived()" << endl;

        func();
    }

    virtual void func()
    {
        cout << "Derived::func()" << endl;
    }

    ~Derived()
    {
        func();

        cout << "~Derived()" << endl;
    }
};


int main()
{
    Base* p = new Derived();

    // ...

    delete p;

    return 0;
}
构造过程:
Base()
Base::func()
Derived()
Derived::func()

析构过程:
Derived::func()
~Derived()
Base::func()
~Base()
12、继承中的强制类型转换

这里写图片描述

13、

这里写图片描述

14、

这里写图片描述

#include <iostream>
#include <string>

using namespace std;

class Base
{
public:
    Base()
    {
        cout << "Base::Base()" << endl;
    }

    virtual ~Base()
    {
        cout << "Base::~Base()" << endl;
    }
};

class Derived : public Base
{

};

int main()
{
    Base* p = new Base;

    Derived* pd = dynamic_cast<Derived*>(p);

    if( pd != NULL )
    {
        cout << "pd = " << pd << endl;
    }
    else
    {
        cout << "Cast error!" << endl;
    }

    delete p;

    return 0;
}
Base::Base()
Cast error!
Base::~Base()

而这样就是正确的;
    Base* p = new Derived;
    Derived* pd = dynamic_cast<Derived*>(p);
Base::Base()
pd = 0x114ac20
Base::~Base()

15、小结

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值