回 帖 发 新 帖 刷新版面

主题:问个问题

class Base
{
    public:
        Base(){cout<<"Base Begin"<<endl;};
        virtual ~Base(){cout<<"Base End"<<endl;};
        virtual void Test()=0;
};
class A:public Base
{
    public:
        void Test()
        {
            cout<<"Test"<<endl;
            return;
        }
        A()
        {
            cout<<"A Begin"<<endl;
            return;
        }
        virtual ~A()
        {
            cout<<"A End"<<endl;
            return;
        }
};
/////////////
int main(int argc,char *argv[])
{
    Base *pBase=new A;
    pBase->Test();
    delete pBase;
    return 0;
}
有个问题,象上面这样写代码,用一个基类指针指向派生类对象,然后DELETE基类指针,同样能调用派生类的析构函数,这样写对吗?如果对的话是不是可以把各种类都继承一个基类,再用这个基类指针来指向派生类对象,想删除任何一种对象时都可以通过删除基类类型的对象指针这样来删除.用的是MINGW32编译器,请各位帮助解答一下.

回复列表 (共7个回复)

沙发

http://baike.baidu.com/view/161302.htm
这里面有这么一段话:
非类的成员函数不能定义为虚函数,类的成员函数中静态成员函数和构造函数也不能定义为虚函数,但可以将析构函数定义为虚函数。实际上,优秀的程序员常常把基类的析构函数定义为虚函数。因为,将基类的析构函数定义为虚函数后,当利用delete删除一个指向派生类定义的对象指针时,系统会调用相应的类的析构函数。而不将析构函数定义为虚函数时,只调用基类的析构函数。

板凳

注意这样的情况http://www.huarw.com/program/C/c02/200904/1682366.html

3 楼

[quote]http://baike.baidu.com/view/161302.htm
将基类的析构函数定义为虚函数后,当利用delete删除一个指向派生类定义的对象指针时,系统会调用相应的类的析构函数。而不将析构函数定义为虚函数时,只调用基类的析构函数。[/quote]
我想问一下可不可以用一个基类类型的指针来删除它的各种派生类的对象,或者说如何在C++中让各种对象能通过一种简单可靠的方式自己删除自己

4 楼

可不可以理解成想用外部的一个函数删除一个对象时,只要传来的参数是指向要被删除的对象的(这个指针可以不是该对象的类型的),该对象的析构函数都会被调用,这是C++编译器的一个特性.不知道对不对.
之所以问这个问题是因为以前看过一篇文章说如果指针类型不对的话就不会调用对象的析构函数,有些疑惑.

5 楼

简单的说:没有问题。

“delete pBase”这条语句实际上做了两件事情。一是调用pBase所指对象的析构函数,二是以pBase为参数,调用operator delete。
“虚函数”存在的意义就是:通过基类的指针(或引用),在运行的时候根据对象实际的类型,找到应该调用的那个函数,然后进行调用。所以对于第一件事情,实际上会调用到class A的析构函数。C++的语法规定,派生类对象在析构之后,会自动析构其基类部分。也就是说,class A的析构函数在完成之后,即将返回时,会调用class Base的析构函数。
第二件事情就没什么好说的了,operator delete相当于是一个全局函数,它负责释放内存。不管这块内存原来是保存了什么对象,但现在对象已经被析构掉,没有了,有的只是一块内存而已,并且这块内存中的数据也是杂乱无章,再也没有所谓“类型”这样的信息了。我们唯一能做的,就是把这块内存释放掉而已。

问题的关键就在这里 —— 基类的析构函数一定要是virtual的!否则,就无法调用到class A的析构函数了。这会造成对象析构不完全。

[quote]可不可以理解成想用外部的一个函数删除一个对象时,只要传来的参数是指向要被删除的对象的(这个指针可以不是该对象的类型的),该对象的析构函数都会被调用[/quote]
现在您应该有正确的认识了。答案是:并不总是这样。完成这个神奇任务的,正是那个被定义为virtual的析构函数。如果析构函数不是virtual的,则情况就会变成:指针看起来是什么类型,就调用什么类型的析构函数。

6 楼

非常感谢。

7 楼

这段程序写的很正确。至少我没看出有什么问题。

我来回复

您尚未登录,请登录后再回复。点此登录或注册