专门做反季的网站二级域名在线扫描
首先给出这样一段概念:
在C++中,当基类包含纯虚函数时,这些纯虚函数在基类中不需要(也不能)有定义。但是,如果基类有一个纯虚析构函数(即析构函数被声明为纯虚函数),那么情况就有些特殊了。纯虚析构函数需要在基类中有声明,但通常也需要在类外提供一个定义(尽管这个定义通常只包含析构函数的空体)。
再通过一段代码更加深入的理解:
#include <iostream> // 基类
class Base {
public: // 纯虚析构函数 virtual ~Base() = 0 { // 注意:在C++11及之前的标准中,纯虚析构函数不能提供实现体 // 但在C++11中开始,纯虚析构函数可以在类定义内部有定义体(作为内联成员函数) // 但在大多数情况下,我们仍然选择将其定义在类定义之外 std::cout << "Base destructor called." << std::endl; } // 纯虚函数 virtual void pureVirtualFunction() = 0; // 其他成员函数 void normalFunction() { std::cout << "Base normal function called." << std::endl; }
}; // 在类定义外部定义纯虚析构函数(如果需要)
Base::~Base() { // 注意:这个定义是可选的,并且如果在类定义内部已经提供了定义体,则不需要这里再定义
} // 派生类
class Derived : public Base {
public: ~Derived() override { std::cout << "Derived destructor called." << std::endl; } // 提供纯虚函数的实现 void pureVirtualFunction() override { std::cout << "Derived pure virtual function called." << std::endl; }
}; int main() { // 由于Base是抽象类,不能直接实例化 // Base* base = new Base(); // 错误 // 创建派生类对象并通过基类指针管理 Base* basePtr = new Derived(); // 调用派生类的纯虚函数 basePtr->pureVirtualFunction(); // 调用基类的普通函数 basePtr->normalFunction(); // 删除对象,会先调用派生类的析构函数,再调用基类的析构函数 delete basePtr; return 0;
}
总结:
-
在C++11及之后的版本中,纯虚析构函数可以在类定义内部直接提供定义体(作为内联成员函数)。但在C++11之前,纯虚析构函数不能在类定义内部提供定义体,它必须在类定义外部定义。
-
在这个例子中,
Base
类是一个抽象类,因为它包含了一个纯虚函数pureVirtualFunction()
。因此,你不能直接实例化Base
类的对象。 -
当你通过基类指针
basePtr
调用delete
时,会首先调用派生类Derived
的析构函数,然后再调用基类Base
的析构函数。这是因为Derived
类的析构函数是通过override
关键字明确指定的,它会先执行自己的清理工作,然后隐式地调用基类的析构函数。如果基类没有纯虚析构函数,并且你试图通过基类指针删除派生类对象,那么只有基类的析构函数会被调用,这可能会导致资源泄漏。
纯虚析构函数的主要目的是确保通过基类指针或引用删除派生类对象时,派生类的析构函数也能被正确调用