c++学习之虚析构和纯虚析构

虚析构和纯虚析构
    多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码

    解决方式:将父类的析构函数改为虚析构或者纯虚析构

虚析构和纯虚析构共性:
        1)可以解决父类指针释放子类对象
        2)都需要有具体的函数实现
虚析构和纯虚析构区别:
        1)如果是纯虚析构,该类属于抽象类,无法实例化对象
        2)如果只是虚析构,在没有纯虚函数的前提下,该类还是可以实例化对象的

虚析构语法:
        virtual ~类名(){}
纯虚析构语法:
        virtual ~类名() = 0;

总结:
        1)虚析构或纯虚析构就是用来解决通过父类指针释放子类对象
        2)如果子类中没有堆区数据,可以不写    为虚析构或纯虚析构
        3)拥有纯虚析构函数的类也属于抽象类

虚析构示例:

        #include 
        using namespace std;

        class Animal {
        public:
            Animal()
            {
                cout << "Animal 构造函数" << endl;
            }

            //如果不加 virtual 下面这个函数不会执行 堆区没释放干净 导致内存泄露
            virtual void Speak() = 0;

            virtual ~Animal()
            {
                cout << "Animal 析构函数" << endl;
            }
        };

        class Cat : public Animal {
        public:
            Cat(string name)
            {
                m_Name = NULL;
                cout << "Cat 构造函数调用" << endl;
                m_Name = new string(name);
            }

            void Speak()
            {
                cout << "this is Cat" << endl;
            }

            ~Cat()
            {
                cout << "Cat 析构函数调用" << endl;
                if (m_Name != NULL) {
                    delete m_Name;
                    m_Name = NULL;
                }
            }

            string* m_Name;
        };

        void test01()
        {
            Animal* B1 = new Cat("TOM");

            B1->Speak();
            delete B1;
            B1 = NULL;
        }

        int main()
        {
            test01();

            system("pause");

            return 0;
        }

纯虚析构示例:

        class Animal {
        public:
            Animal()
            {
                cout << "Animal 构造函数" << endl;
            }

            virtual void Speak() = 0;

            //虚析构:如果不加 virtual 下面这个函数不会执行 堆区没释放干净 导致内存泄露
            //virtual ~Animal()
            //{
            //    cout << "Animal 析构函数" << endl;
            //}

            //纯虚析构:
            virtual ~Animal() = 0;
        };

        //析构函数中必须要写点东西,比如如果父类中有堆区的内存要释放。 类里面因为纯虚析构的语法构造,我们只能在类外通过作用域写了
        Animal::~Animal()
        {
            cout << "Animal 析构函数" << endl;
        }

你可能感兴趣的:(c++)