面试时被问到了虚析构函数的使用,特此记录
首先我们写两个类:
#ifndef CLX_H #define CLX_H #include <iostream> class ClxBase { public: ClxBase() {std::cout << "clx_base has been created" << std::endl;} virtual ~ClxBase() {std::cout << "clx_base has been destroyed" << std::endl;} virtual void dosomething() {std::cout << "clx_base dosomething..." << std::endl;} }; class ClxDerived : public ClxBase { public: ClxDerived() {std::cout << "clx_derived has been created" << std::endl;} ~ClxDerived(){std::cout << "clx_derived has been destroyed" << std::endl;} void dosomething() {std::cout << "clx_derived dosomething..." << std::endl;} }; #endif
指明了,父类的析构函数是虚类型。
调用代码:
ClxBase *clx = new ClxDerived; clx->dosomething(); delete clx;
运行结果如下:
注意类加载时的顺序和析构的顺序是刚好相反的。析构是总是从子类开始,然后再回收父类,符合编程要求。
如果将父类中规定的虚类型去掉,即
class ClxBase { public: ClxBase() {std::cout << "clx_base has been created" << std::endl;} ~ClxBase() {std::cout << "clx_base has been destroyed" << std::endl;} virtual void dosomething() {std::cout << "clx_base dosomething..." << std::endl;} };
这样,只会执行基类的析构函数,而派生类的析构函数不会执行。 相当于没有重载。
运行效果如下:
当基类的析构函数为虚函数时,无论指针指的是同一类族中的哪一个类对象,系统会采用动态关联,调用相应的析构函数,对该对象进行清理工作。
如果将基类的析构函数声明为虚函数时,由该基类所派生的所有派生类的析构函数也都自动成为虚函数,即使派生类的析构函数与基类的析构函数名字不相同。
最好把基类的析构函数声明为虚函数。这将使所有派生类的析构函数自动成为虚函数。这样,如果程序中显式地用了delete运算符准备删除一个对象,而delete运算符的操作对象用了指向派生类对象的基类指针,则系统会调用相应类的析构函数。
虚析构函数的概念和用法很简单,但它在面向对象程序设计中却是很重要的技巧。
专业人员一般都习惯声明虚析构函数,即使基类并不需要析构函数,也显式地定义一个函数体为空的虚析构函数,以保证在撤销动态分配空间时能得到正确的处理。
构造函数不能声明为虚函数。这是因为在执行构造函数时类对象还未完成建立过程,当然谈不上函数与类对象的绑定。
相关推荐
C++中虚析构函数的作用是为了确保当使用基类的指针删除派生类的对象时,派生类的析构函数被正确调用。这种机制可以防止内存泄漏和其他潜在的问题。 在C++中,析构函数是用来释放对象占用的资源的。通常情况下,析构...
本文将深入探讨虚析构函数的作用、工作原理以及何时需要使用它。 首先,我们来理解什么是析构函数。析构函数是C++中的一个特殊成员函数,其作用是在对象生命周期结束时自动调用,用于清理对象占用的资源,如释放...
在`8_5虚析构函数.cpp`中,可能包含了关于正确使用虚析构函数防止内存问题的代码片段。 在实际编程中,理解并熟练运用这三个概念可以极大地提高代码的可维护性和扩展性。虚基类保证了继承层次的清晰,虚函数提供了...
在 C++ 中,基类的析构函数如果不使用 virtual 虚析构函数,可能会导致内存泄漏。那么,为什么基类的析构函数需要使用 virtual 虚析构函数?下面我们来详细解释。 首先,需要了解 C++ 中的动态绑定。动态绑定是指在...
对于虚析构函数来说,虚函数表的存在使得可以根据实际对象的类型来决定调用哪个析构函数,从而实现了在对象销毁时的逆序操作:先调用派生类的析构函数,然后调用基类的析构函数,以保证派生类中新增的资源也能被正确...
} // 非虚析构函数 private: char* ptr_a_; }; class B : public A { public: B() { ptr_b_ = new char[20]; } ~B() { delete[] ptr_b_; } // 派生类的析构函数 private: char* ptr_b_; }; void foo() { A* ...
2. **动态绑定的正确性**:在类的继承体系中,通过虚析构函数可以确保动态绑定正确地执行。当通过基类指针删除派生类对象时,动态绑定机制将识别到实际类型并调用相应的析构函数。 3. **代码可扩展性和安全性**:...
C++中虚析构函数的作用及其原理分析 C++中的虚析构函数是一种特殊的析构函数,用于避免内存泄露和防止内存泄露。当子类中有指针成员变量时,虚析构函数可以确保在删除基类指针时调用子类的析构函数,以释放子类中的...
当通过基类指针或引用调用虚析构函数时,会调用对应的派生类析构函数,实现了多态性。 3. **提高代码健壮性和可维护性**:对于大型项目来说,良好的设计习惯至关重要。将基类的析构函数声明为虚函数可以减少未来...
1. **动态类型与静态类型不匹配**:在析构函数中调用虚函数时,C++使用的是静态绑定,即根据对象的静态类型(即编译时已知的类型)来决定调用哪个函数版本,而不是动态类型(即运行时的实际类型)。因此,即使你期望...
3. **声明虚析构函数:** 如果一个类有可能被继承,则应该声明虚析构函数,以确保正确的析构顺序。 4. **遵循RAII原则:** 使用资源获取即初始化(Resource Acquisition Is Initialization, RAII)的设计模式,利用...
6. **可以是虚函数**:如果希望在派生类中覆盖基类的析构函数,则可以在基类中声明析构函数为虚函数。 #### 三、示例代码解析 下面通过给出的代码示例来详细了解析构函数的应用: ```cpp #include using ...
在有继承层次结构的类中,基类的析构函数通常是虚函数(`virtual`),以确保即使通过基类指针或引用删除派生类对象时,也能调用正确的析构函数。例如: ```cpp class Base { public: virtual ~Base() { // 基类析...
在C++编程语言中,虚函数(Virtual Functions)和虚析构函数(Virtual Destructors)是面向对象编程中的重要概念,特别是在处理继承和多态性时显得尤为关键。本资料详细介绍了这两个主题,并通过实例进行了深入讲解...
虚析构函数 析构函数的工作方式是:底层的派生类(most derived class)的析构函数先被调用,然后调用每一个基类的析构函数。 因为在C++中,当一个派生类对象通过使用一个基类指针删除,而这个基类有一个非...
基类的析构函数默认是虚函数(virtual),这样在派生类的对象指针指向基类时,如果通过指针调用析构函数,会执行相应的派生类析构函数,确保所有资源都能被正确释放。这是因为C++支持动态绑定或称为运行时多态。 ...
C++中,有两种类型的析构函数:非虚析构函数和虚析构函数。对于基类,如果基类的析构函数声明为虚的(`virtual`),那么通过基类指针或引用删除派生类对象时,将调用正确的派生类析构函数,这是多态性的体现。不声明...
在C++编程语言中,虚析构函数(Virtual Destructor)是一个非常关键的概念,它主要用于处理多态性(Polymorphism)和动态类型(Dynamic ...因此,在设计基类时,明智地使用虚析构函数可以提高代码的健壮性和可维护性。
//析构函数做成员函数 }; Base::~Base()//成员函数实现 { cout; } class Derived:public Base { public: Derived(); ~Derived(); private: int *p; }; Derived::Derived() { p=new int(0);//从堆上分配一个int型...