基类析构函数为虚函数

代码:析构函数为非虚函数

#include <iostream>

using namespace std;

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

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

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

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

int main(int argc, char** argv)
{
    A *pa = new B();
    delete pa;

    B *pb = new B();
    delete pb;
}

输出:

A
B
~A
A
B
~B
~A

指向子类对象的基类指针,析构过程未调用子类的析构函数,若子类申请内存空间,则将无法被释放,导致内存泄漏。

代码:析构函数为虚函数

#include <iostream>

using namespace std;

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

        virtual ~A()
        {
            cout << "~A" << endl;
        }
};

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

        virtual ~B()
        {
            cout << "~B" << endl;
        }
};

int main(int argc, char** argv)
{
    A *pa = new B();
    delete pa;

    B *pb = new B();
    delete pb;
}

输出:

A
B
~B
~A
A
B
~B
~A

指向子类对象的基类指针,析构过程先调用子类析构函数,再调用基类析构函数。

若析构函数为非虚函数时,delete p 会直接调用相应指针类型的析构函数 即父类析构函数。若析构函数为虚函数时,则会调用实际对象的析构函数,即子类析构函数,子类继承自父类,子类析构函数调用完,会接着调用父类析构函数。

时间: 2024-10-08 03:16:28

基类析构函数为虚函数的相关文章

C++:抽象基类和纯虚函数的理解

转载地址:http://blog.csdn.net/acs713/article/details/7352440 抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层. ⑴抽象类的定义: 称带有纯虚函数的类为抽象类. ⑵抽象类的作用: 抽象类的主要作用是将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操作.所以派生类实际上刻画了一组子类的操作接口的通用语义,这些语义也传给子类,子类可以具体实现这些

C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构

一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型,我们如果想通过一个父类指针调用父类.子类中的同名函数的话,这个函数是有要求的: 在父类中,eat函数声明之前必须要加virtual声明eat()函数为虚函数. 一旦某个函数被声明为虚函数,那么所有派生类(子类)中eat()函数都是虚函数. 为了避免你在子类中写错虚函数,在C++11中,你可以在函数

C++学习笔记(十二):类继承、虚函数、纯虚函数、抽象类和嵌套类

类继承 在C++类继承中,一个派生类可以从一个基类派生,也可以从多个基类派生. 从一个基类派生的继承称为单继承:从多个基类派生的继承称为多继承. 1 //单继承的定义 2 class B:public A 3 { 4 < 派生类新定义成员> 5 }; 6 //多继承的定义 7 class C:public A,private B 8 { 9 < 派生类新定义成员> 10 }; 我们这篇主要说单继承. 派生类共有三种C++类继承方式: 公有继承(public) 基类的公有成员和保护成

基类中的虚方法到底有什么作用?

只有基类的方法加上关键字virtual后才可以被override,从而实现面向对象最重要的特征--多态性,即基类可以使用派生类的方法. C#中指出:普通的方法重载:指的是类中两个以上的方法(包括隐藏的,继承而来的方法)取的名字相同,只要使用的参数类型或者参数个数不同,编译器便知道在何种情况下应该调用哪个方法.   而在派生类中重新定义此虚函数时要求的是:方法名称.返回值类型.参数表中的参数个数.类型.顺序都必须与基类中的虚函数完全一致. 简单一点说就是子类中override的方法能够覆盖积累中的

空类,含有虚函数的类的大小

1.为何空类的大小不是0呢? 为了确保两个不同对象的地址不同,必须如此. 类的实例化是在内存中分配一块地址,每个实例都有独一无二的内存地址.空类也会实例化,为保证空类实例化后的独一无二性,编译器会给空类隐含的添加一个字节.所以,空类的sizeof为1,而不是0. 2.继承关系中的类大小: case 1: 父类有虚函数,子类继承. class A{ virtual void f(){} }; class B:public A{} 此时,类A和类B都不是空类,其sizeof都是4,因为它们都具有虚函

(C++)浅谈多态基类析构函数声明为虚函数

主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.C++多态性中析构函数声明为虚函数 1.C++类继承中的构造函数和析构函数 在C++的类继承中, 建立对象时,首先调用基类的构造函数,然后在调用下一个派生类的构造函数,依次类推: 析构对象时,其顺序正好与构造相反: 具体参考文章:http://www.cnblogs.com/AndyJee/p/4575385.html 2.C++多态性中的静态绑定和动态绑定 对象的静态类型:对象在声明是采用的类型,在

为多态基类声明一个虚析构函数

使用一个基类指针删除派生类对象,同时基类的析构函数是非虚的,那么这个指针只会删除派生类对象中的基类的部分,其派生部分不会被删除.造成资源泄漏. 而如果一个类并不用作基类,则没必要把析构函数声明为虚的,否则会浪费空间来存储虚函数指针和虚函数表. STL容器并不含虚析构函数,因此最好不要继承STL容器. 只要有一个纯虚函数,就会导致抽象基类,即不能声明该基类的对象.抽象基类只能用来继承,纯虚函数如: virtual ~AWOV() = 0; 你必须为这个纯虚析构函数提供定义,因为析构函数调用时,最先

为什么析构函数是虚函数比较好?

原因:基类对象的指针操作派生类对象时,防止析构函数只调用基类的,而不调用派生类的 下面详细说明: //基类 class A{ public : A(){ cout<<"A构造函数"<<endl; } ~A(){cout<<"A被销毁了"<<endl;} void Do(){ cout<<"A要做点什么"<<endl; } }; //派生类 class B :public A{

C++中为什么构造函数不能是虚函数,析构函数是虚函数

一, 什么是虚函数? 简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离:用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略. 所谓虚函数就是多态情况下只执行一个,而从继承的概念来讲,总是要先构造父类对象,然后才能是子类对象,如果构造函数设为虚函数,那么当你在构造父类的构造函数时就不得不显示的调用构造,还有一个原因就是为了防错,试想如果你在子类中一不小心重写了个跟