析构函数多态的问题

来源:互联网 发布:广东飞鱼网络 编辑:程序博客网 时间:2024/05/16 08:59

在学习虚函数时,遇到了一个问题。析构函数多态的实现,在一定条件下不需要设定为虚函数。代码如下:

#include<iostream>using namespace std;class base {public:    base() {        cout << "base is running" << endl;    }    ~base() {        cout << "base is destroying" << endl;    }    virtual void shut() {        cout << "base is shuting" << endl;    }    virtual void paint() = 0;    virtual int shoot() = 0;};class man : public base {public:    man() {        cout << "man is running " << endl;    }    ~man() {        cout << "man is destroying" << endl;    }    void shut() {        cout << "the man is shuting" << endl;    }    void paint() {        cout << "man is painting" << endl;    }    int shoot() {        return (1);    }};class woman : public base {public:    woman() {        cout << "woman is running" << endl;    }    ~woman() {        cout << "woman is destroying" << endl;    }    void shut() {        cout << "the woman is shuting" << endl;    }    void paint() {        cout << "woman is painting " << endl;    }    int shoot() {        return (2);    }};int main() {    base *b;    man m;    woman w;    b = &m;    b->shut();    b->paint();    cout << "man's shoot: " << b->shoot() << endl;    b = &w;    b->shut();    b->paint();    cout<<"woman's shoot"<<b->shoot()<<endl;}

运行结果为:
图一
基类base的析构函数并没有设定为虚函数,但是运行结果显示为先析构继承类,再析构基类。
将代码略作修改,采用new的方法进行实例化,如下:

#include<iostream>using namespace std;class base {public:    base() {        cout << "base is running" << endl;    }    ~base() {        cout << "base is destroying" << endl;    }    virtual void shut() {        cout << "base is shuting" << endl;    }    virtual void paint() = 0;    virtual int shoot() = 0;};class man : public base {public:    man() {        cout << "man is running " << endl;    }    ~man() {        cout << "man is destroying" << endl;    }    void shut() {        cout << "the man is shuting" << endl;    }    void paint() {        cout << "man is painting" << endl;    }    int shoot() {        return (1);    }};class woman : public base {public:    woman() {        cout << "woman is running" << endl;    }    ~woman() {        cout << "woman is destroying" << endl;    }    void shut() {        cout << "the woman is shuting" << endl;    }    void paint() {        cout << "woman is painting " << endl;    }    int shoot() {        return (2);    }};int main() {    base *b= new man;    b->shut();    b->paint();    cout << "man's shoot: " << b->shoot() << endl;    base *c = new woman;    c->shut();    c->paint();    cout<<"woman's shoot"<<c->shoot()<<endl;    delete b;    delete c;}

运行结果为:
图片二
发现只析构了基类,并没有析构继承类。
再将代码略作修改,将基类的析构函数虚函数化,代码如下:

#include<iostream>using namespace std;class base {public:    base() {        cout << "base is running" << endl;    }    virtual~base() {        cout << "base is destroying" << endl;    }    virtual void shut() {        cout << "base is shuting" << endl;    }    virtual void paint() = 0;    virtual int shoot() = 0;};class man : public base {public:    man() {        cout << "man is running " << endl;    }    ~man() {        cout << "man is destroying" << endl;    }    void shut() {        cout << "the man is shuting" << endl;    }    void paint() {        cout << "man is painting" << endl;    }    int shoot() {        return (1);    }};class woman : public base {public:    woman() {        cout << "woman is running" << endl;    }    ~woman() {        cout << "woman is destroying" << endl;    }    void shut() {        cout << "the woman is shuting" << endl;    }    void paint() {        cout << "woman is painting " << endl;    }    int shoot() {        return (2);    }};int main() {    base *b= new man;    b->shut();    b->paint();    cout << "man's shoot: " << b->shoot() << endl;    base *c = new woman;    c->shut();    c->paint();    cout<<"woman's shoot"<<c->shoot()<<endl;    delete b;    delete c;}

运行结果与实验一相似,只是析构顺序有所改变,结果贴图如下:
图三

问题就出在new实例化与直接实例化的区别上。
直接实例化内存开在栈中,由操作系统进行管理,不会出现资源泄露的情况。而new进行实例化,内存开在堆中,由程序员进行管理。这可能就是为什么new实例化需要对析构函数进行虚函数化的原因。
至于析构顺序,也是在栈和堆的区别上进行找原因。

操作系统中所说的堆内存和栈内存,在操作上有上述的特点,这里的堆内存实际上指的就是(满足堆内存性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈内存实际上就是满足先进后出的性质的数学或数据结构。
百度百科中找到的两者的粗浅介绍。堆是队列性质的数据结构,先入先出;栈是先入后出。所以析构顺序不同。

原创粉丝点击