经典问题解析

Posted 学习只为旅行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典问题解析相关的知识,希望对你有一定的参考价值。



#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;
}

free可以释放new的空间,但是不会调用析构函数,所以有可能造成内存泄漏


构造 析构 虚函数



将析构函数声明为虚函数有啥用?

#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()
{
	//由于父类析构函数为虚函数,所以调用delete的时候
	//编译器不会暴力的直接调用Base中的析构函数,而是
	//先调用p指向的对象空间中的析构函数,即子类析构函数
	//再调用父类的析构函数(构造与析构顺序相反!)
    Base* p = new Derived();
    
    // ...
    
    delete p;
    
    return 0;
}


如果父类析构函数不是虚函数,那么存在像上面注释提到的情况的话,编译器会跳过子类析构函数,直接执行父类的析构函数,会导致内存泄漏!后果不堪设想!那么这就是析构函数成为虚函数的意义所在!



强制类型转换



#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);
    //这里的强制类型转换没有成功,返回NULL
    
    if( pd != NULL )
    {
        cout << "pd = " << pd << endl;
    }
    else
    {
        cout << "Cast error!" << endl;
    }
    
    delete p;
    
    return 0;
}


这个倒是合法的!

小结

以上是关于经典问题解析的主要内容,如果未能解决你的问题,请参考以下文章

无法解析片段中的 ViewModelProvider 构造?

C语言100个经典算法源码片段

无法解析片段中的 findViewById [重复]

二级域名原理以及程序代码

片段(Java) | 机试题+算法思路+考点+代码解析 2023

Relay.js 没有正确解析组合片段