C++ 虚析构函数
一个 析构函数 在C++中是一个类的成员函数,用于释放由该类占用的空间或删除超出作用域的类的对象。析构函数与类中的构造函数具有相同的名称,但在函数名之前使用波浪号 (~) 。
虚析构函数
虚析构函数用于释放由派生类对象或实例分配的内存空间,同时使用基类指针对象删除派生类的实例。基类或父类的析构函数使用 virtual 关键字,确保基类和派生类的析构函数将在运行时被调用,但它首先调用派生类,然后是基类,以释放两个析构函数占用的空间。
为什么在C++中使用虚析构函数
当类中的对象超出作用域或main()函数的执行即将结束时,析构函数会自动调用程序来释放类的析构函数所占用的空间。当删除指向派生类的基类指针对象时,由于编译器的早期绑定,只调用父类的析构函数。这种情况下,会跳过调用派生类的析构函数,导致程序中的内存泄漏问题。当我们在基类中使用虚拟关键字作为析构函数波浪线 (~) 的前缀时,它确保首先调用派生类的析构函数,然后调用基类的析构函数,以释放继承类中两个析构函数占用的空间。
编写一个程序在C ++中展示类析构函数的未定义行为,但不使用虚析构函数
#include<iostream>
using namespace std;
class Base
{
public: /* A public access specifier defines Constructor and Destructor function to call by any object in the class. */
Base() // Constructor function.
{
cout<< "\n Constructor Base class";
}
~Base() // Destructor function
{
cout<< "\n Destructor Base class";
}
};
class Derived: public Base
{
public: /* A public access specifier defines Constructor and Destructor function to call by any object in the class. */
Derived() // Constructor function
{
cout << "\n Constructor Derived class" ;
}
~Derived() // Destructor function
{
cout << "\n Destructor Derived class" ; /* Destructor function is not called to release its space. */
}
};
int main()
{
Base *bptr = new Derived; // Create a base class pointer object
delete bptr; /* Here pointer object is called to delete the space occupied by the destructor.*/
}
输出:
从上述输出可以看出,当编译器编译代码时,在主函数中调用指向基类的指针对象。因此,它执行基类的构造函数,然后转到派生类的构造函数。然后,它删除由基类析构函数和派生类析构函数占用的指针对象。程序中,基类指针只删除基类的析构函数而不调用派生类的析构函数。所以,程序中会发生内存泄漏。
注意:如果基类的析构函数没有使用虚关键字,仅会调用基类的析构函数或删除其占用的空间,因为指针对象指向基类。所以它不会调用派生类的析构函数来释放派生类使用的内存,这导致派生类发生内存泄漏。
请编写一个使用虚析构函数来展示类析构函数行为的C++程序
#include<iostream>
using namespace std;
class Base
{
public:
Base() // Constructor member function.
{
cout << "\n Constructor Base class"; // It prints first.
}
virtual ~Base() // Define the virtual destructor function to call the Destructor Derived function.
{
cout << "\n Destructor Base class"; /
}
};
// Inheritance concept
class Derived: public Base
{
public:
Derived() // Constructor function.
{
cout << "\n Constructor Derived class" ; /* After print the Constructor Base, now it will prints. */
}
~Derived() // Destructor function
{
cout << "\n Destructor Derived class"; /* The virtual Base Class? Destructor calls it before calling the Base Class Destructor. */
}
};
int main()
{
Base *bptr = new Derived; // A pointer object reference the Base class.
delete bptr; // Delete the pointer object.
}
输出:
在上述程序中,我们在基类中使用了虚析构函数,该函数在调用基类析构函数之前调用派生类的析构函数,从而释放空间或解决程序中的内存泄漏问题。