您的位置:首页 > 其它

关于多态里父类的析构函数造成子类内存泄露的问题

2014-03-18 17:42 387 查看
最近在学c++,学到多态,发现一个有趣的问题,先来看一段代码:

#include <iostream>

using namespace std;

class Database{
    public:
        virtual void connect(){cout << "Database connected!" << endl;}
        virtual void query()const{cout << "Database queried!" << endl;}
        Database(){cout << "Database" << endl;}
        ~Database(){cout << "~Database" << endl;}
};

class Access : public Database{
    public:
        virtual void connect(){cout << "Access connected!" << endl;}
        virtual void query()const{cout << "Access queried!" << endl;}
        Access(){cout << "Access" << endl;}
        ~Access(){cout << "~Access" << endl;}
    
};

class SQLServer : public Database{
    public:
        virtual void connect(){cout << "SQLServer connected!" << endl;}
        virtual void query()const{cout << "SQLServer queried!" << endl;}
        SQLServer(){cout << "SQLServer" << endl;}
        ~SQLServer(){cout << "~SQLServer" << endl;}
    
};

class Oracle : public Database{
    public:
        virtual void connect(){cout << "Oracle connected!" << endl;}
        virtual void query()const{cout << "Oracle queried!" << endl;}
        Oracle(){cout << "Oracle" << endl;}
        ~Oracle(){cout << "~Oracle" << endl;}
    
};

class Program{
    public:
        void visit(Database* p){ 
            p->query();
            p->connect();
        }
    Program(){cout << "Program" << endl;}
    ~Program(){cout << "~Program" << endl;}
};
int main()
{
    Database* q1 = new Access;
    Database* q2 = new SQLServer;
    Database* q3 = new Oracle;
    Program* p = new Program;
    p->visit(q1);
    p->visit(q2);
    p->visit(q3);

    delete q1;
    delete q2;
    delete q3;
    delete p;
    return 0;
}


只需要看main函数里的,Database为父类,Access、SQLServer和Oracle都是继承了Database的子类,而Program为调用一个Database对象的类。之前new申请动态内存都没有问题,一直到调用结束,我们想用delete来释放内存空间的时候,结果显示为:

,怎么只释放了父类对象的空间而没有释放子类对象?这是因为没有在父类的析构函数前加上关键字
virtual,实际上,许多人的经验是,只要父类里定义了virtual的成员函数,则虚构函数几乎都需要加上virtual,我们把virtual加到父类的析构函数之前,再来看结果:

,这是一切正常了。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: