美文网首页
虚析构函数

虚析构函数

作者: __freetime | 来源:发表于2017-03-23 12:42 被阅读20次

    虚析构函数

    #include <iostream>
    #include<string>
    #include<cstdlib>
    
    using namespace std;
    
    class A
    {
    public:
        ~A()
        {
            cout << "A destructor" << endl;
        }
    };
    class B :public A
    {
        ~B()
        {
            cout << "B destructor" << endl;
        }
    };
    
    int main()
    {
        A *pa = new B;
        delete pa;
        return 0;
    }
    
    
    运行结果:
    
    A destructor    // 只引发了 A 类的析构函数被调用,没有引发 B 类的析构函数
    

    当将基类指针指向 new 运算符动态生成的派生类对象时,要通过 delete 来释放,应为该语句是静态联编的,编译器不可能知道此时 pa 指向哪个类型的对象,它只是根据 pa 类型是 A * ,来决定调用 A 类的析构函数,但实际上应该调用 B 类的析构函数才符合逻辑。

    综上,delete pa 这样的语句应该根据 pa 所指的对象,来执行相应的析构函数。要实现这点,也用到了多态。因此,需要将基类的析构函数声明为虚函数,即虚析构函数。

    改为:

    class A
    {
        virtual ~A()
        {
            cout << "A destructor" << endl;
        }
    }
    
    运行结果:
    
    B destructor
    A destructor
    

    注意

    1. 派生类的析构函数会自动调用基类的析构函数。

    2. 一般,如果一个类定义了虚函数,则最好将析构函数也定义成虚函数。

    3. 只要在基类中某个函数被声明为虚函数,那么在派生类中,同名,同参数表的成员函数即使前面不写 virtual 关键字,也自动成为虚函数。

    4. 编译器看到是哪个类的指针,那么就会认为通过它访问的,就应该是哪个类的成员,编译器不会分析基类指针到底指向的是基类对象还是派生类对象。

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
        void fun()
        {
            cout << "A called" << endl;
        }
    };
    class B :public A
    {
        void fun()
        {
            cout << "B called" << endl;
        }
    };
    int main(void)
    {
        B b;
        A *pa = &b;
        pa->fun();
    
        return 0;
    }
    
    运行结果:
    
    A called
    

    如果用上多态,则解决了这个问题:

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
        virtual void fun()
        {
            cout << "A called" << endl;
        }
    };
    class B :public A
    {
        void fun()
        {
            cout << "B called" << endl;
        }
    };
    int main(void)
    {
        B b;
        A *pa = &b;
        pa->fun();
    
        return 0;
    }
    
    运行结果:
    
    B called
    

    由上,只在基类 A 中的 fun 函数前加了关键字 virtual (line 120),是该函数及其派生类中的同名,同参数表中的成员函数自动成为了虚函数,通过基类的指针调用虚函数时,就用到了多态。

    相关文章

      网友评论

          本文标题:虚析构函数

          本文链接:https://www.haomeiwen.com/subject/fipznttx.html