[转载]析构函数的虚析构和非虚析构调用的差别

代码示例:

非虚析构的情况下.

#include <stdio.h>
#include <iostream>

using namespace std;

class A
{
public:
        A()
        {
                std::cout << "A is created." << std::endl;
        }

        ~A()
        {
                std::cout << "A is deleted." << std::endl;
        }
};

class B : public A
{
public:
        B()
        {
                std::cout << "B is created." << std::endl;
        }

        ~B()
        {
                std::cout << "B is deleted." << std::endl;
        }
};

int main()
{
    A* pA = new B();
    delete pA;
    return 0;
}

虚析构的情况下.

#include <stdio.h>
#include <iostream>

using namespace std;

class A
{
public:
        A()
        {
                std::cout << "A is created." << std::endl;
        }

        virtual ~A()
        {
                std::cout << "A is deleted." << std::endl;
        }
};

class B : public A
{
public:
        B()
        {
                std::cout << "B is created." << std::endl;
        }

        ~B()
        {
                std::cout << "B is deleted." << std::endl;
        }
};

int main()
{
    A* pA = new B();
    delete pA;
    return 0;
}

如果在类型B中创建了一些资源,比如文件句柄、内存等,在这种情况下都得不到释放,从而导致资源泄漏。

时间: 2024-08-03 09:40:48

[转载]析构函数的虚析构和非虚析构调用的差别的相关文章

C++虚函数与非虚函数的区别。

#include <iostream> #include <string> /* * Animal 与Dog之间没有虚函数 * Animal Fish有一个eating的虚函数 * 通过"基类的指针" 访问 子类(们)的成员函数.这叫动态多态.是用虚函数的技术完成的.这也叫动态绑定.] * 当我们使用基类的引用(或指针)调用一个虚函数时将发生动态绑定(dynamic binding) 因为我们直到运行时才能知道到底调用了哪个版本的虚函数,可能是基类中的版本也可能

【C/C++学院】0823-静态联合编译与动态联合编译/父类指针子类指针释放/虚函数/纯虚函数概念以及虚析构函数/抽象类与纯虚函数以及应用/虚函数原理/虚函数分层以及异质链表/类模板的概念以及应用

静态联合编译与动态联合编译 #include <iostream> #include <stdlib.h> //散列 void go(int num) { } void go(char *str) { } //class //::在一个类中 class A { public: void go(int num) { } void go(char *str) { } }; void main() { ///auto p = go;编译的阶段,静态联编 void(*p1)(char *s

虚函数、纯虚函数、虚函数与析构函数

一.虚函数 只有用virtual声明类的成员函数,使之成为虚函数,不能将类外的普通函数声明为虚函数.因为虚函数的作用是允许在派生类中对基类的虚函数重新定义.所以虚函数只能用于类的继承层次结构中. 一个成员函数被声明为虚函数后,在同一类族中的类就不能再定义一个非virtual的但与该虚函数具有相同的参数(包括个数和类型)和函数返回值类型的同名函数. 根据什么考虑是否把一个成员函数声明为虚函数? ①  看成员函数所在的类是否会作为基类 ② 看成员函数在类的继承后有无可能被更改功能,如果希望更改其功能

虚析构和纯虚析构

虚析构和纯虚析构的共性 1.可以解决父类指针释放子类对象 2.都需要具体的函数实现 虚析构和纯虚析构的区别 如果是纯虚析构,则该类属于抽象类,无法实例化对象 虚析构语法 virtual ~类名(){} 纯虚析构 virtual ~类名() = 0 纯虚析构的类外实现 类名::~类名(){} 1 #include<bits/stdc++.h> 2 #include<iostream> 3 using namespace std; 4 5 class Animal 6 { 7 publ

C++虚函数表与虚析构函数

1.静态联编和动态联编联编:将源代码中的函数调用解释为要执行函数代码. 静态联编:编译时能确定唯一函数.在C中,每个函数名都能确定唯一的函数代码.在C++中,因为有函数重载,编译器须根据函数名,参数才能确定唯一的函数代码. 动态联编:编译时不能确定调用的函数代码,运行时才能.C++中因为多态的存在,有时编译器不知道用户将选择哪种类型的对象,因此无法确定调用的唯一性,只有在运行时才能确定. 2.虚成员函数,指针或引用,动态联编指针或引用才能展现类的多态性.当类中的方法声明为virtual时,使用指

条款36:绝不重新定义继承而来的非虚函数

1 #include <iostream> 2 3 using namespace std; 4 5 class Base 6 { 7 public: 8 void mf(); 9 }; 10 void Base::mf() 11 { 12 cout << "Base::mf" << endl; 13 } 14 15 class Derived : public Base 16 { 17 public: 18 void mf(); 19 }; 20

TControl的显示函数(5个非虚函数,4个虚函数)和三个例子的执行过程(包括SetParent的例子)

// 9个显示函数 procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); virtual; // 虚函数,important 根据父控件 // 手法:固定不变的模式,或者简单调用,或者简单设置标志位,就不是虚函数. procedure Show; // 设置自己和所有祖先的visible标识 procedure Hide; // 简单设置visible标识,与祖先无关 procedure Refresh; // 简单调用Repai

条款37: 决不要重新定义继承而来的非虚函数

class B { public: void mf(); ... }; class D: public B { ... }; 甚至对B,D或mf一无所知,也可以定义一个类型D的对象x, D x;                          // x是类型D的一个对象 那么,如果发现这么做: B *pB = &x;                   // 得到x的指针 pB->mf();                     // 通过指针调用mf 和下面这么做的执行行为不一样: D

父类指针指向子类实例:同名非虚函数

场景描述:如果父类指针指向子类的实例,并且调用的函数是一个子类和父类同名的函数,并且这个函数没有被定义为虚函数,肯定无法通过父类指针调用子类的接口.测试代码如下: class CFather{ public:      void Display()     {         cout<<"Father display"<<endl;     } }; class CSon:public CFather { public:      void Display()