• 析构函数什么情况下要定义为虚函数?


     1 1.第一段代码
     2 #include<iostream>
     3 using namespace std;
     4 class ClxBase{
     5 public:
     6     ClxBase() {};
     7     ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;};
     8     void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
     9 };
    10 class ClxDerived : public ClxBase{
    11 public:
    12     ClxDerived() {};
    13     ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; };
    14     void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
    15 };
    16   int   main(){  
    17   ClxDerived *p =  new ClxDerived;
    18   p->DoSomething();
    19   delete p;
    20   return 0;
    21   }
    22 运行结果: 23 Do something in class ClxDerived! 24 Output from the destructor of class ClxDerived! 25 Output from the destructor of class ClxBase! 26 这段代码中基类的析构函数不是虚函数,在main函数中用继承类的指针去操作继承类的成员,释放指针P的过程是:先释放继承类的资源,再释放基类资源. 27

    28 2.第二段代码 29 #include<iostream> 30 using namespace std; 31 class ClxBase{ 32 public: 33 ClxBase() {}; 34 ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;}; 35 void DoSomething() { cout << "Do something in class ClxBase!" << endl; }; 36 }; 37 class ClxDerived : public ClxBase{ 38 public: 39 ClxDerived() {}; 40 ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; }; 41 void DoSomething() { cout << "Do something in class ClxDerived!" << endl; } 42 }; 43 int main(){ 44 ClxBase *p = new ClxDerived; 45 p->DoSomething(); 46 delete p; 47 return 0; 48 } 49 输出结果: 50 Do something in class ClxBase! 51 Output from the destructor of class ClxBase! 52 这段代码中基类的析构函数同样不是虚函数,不同的是在main函数中用基类的指针去操作继承类的成员,释放指针P的过程是:只是释放了基类的资源,而没有调用继承类的析构函数.调用dosomething()函数执行的也是基类定义的函数. 53 一般情况下,这样的删除只能够删除基类对象,而不能删除子类对象,形成了删除一半形象,造成内存泄漏. 54 在公有继承中,基类对派生类及其对象的操作,只能影响到那些从基类继承下来的成员.如果想要用基类对非继承成员进行操作,则要把基类的这个函数定义为虚函数. 55 析构函数自然也应该如此:如果它想析构子类中的重新定义或新的成员及对象,当然也应该声明为虚的. 56 57 3.第三段代码: 58 #include<iostream> 59 using namespace std; 60 class ClxBase{ 61 public: 62 ClxBase() {}; 63 virtual ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;}; 64 virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; }; 65 }; 66 class ClxDerived : public ClxBase{ 67 public: 68 ClxDerived() {}; 69 ~ClxDerived() { cout << "Output from the destructor of class ClxDerived!" << endl; }; 70 void DoSomething() { cout << "Do something in class ClxDerived!" << endl; }; 71 }; 72 int main(){ 73 ClxBase *p = new ClxDerived; 74 p->DoSomething(); 75 delete p; 76 return 0; 77 } 78 运行结果: 79 Do something in class ClxDerived! 80 Output from the destructor of class ClxDerived! 81 Output from the destructor of class ClxBase! 82 这段代码中基类的析构函数被定义为虚函数,在main函数中用基类的指针去操作继承类的成员,释放指针P的过程是:只是释放了继承类的资源,再调用基类的析构函数.调用dosomething()函数执行的也是继承类定义的函数. 83 84 如果不需要基类对派生类及对象进行操作,则不能定义虚函数,因为这样会增加内存开销.当类里面有定义虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间.所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数.

    转载自:http://blog.sina.com.cn/s/blog_7c773cc50100y9hz.html

  • 相关阅读:
    进击Node.js基础(一)
    关于bootstrap两个模态框的问题
    系列博文-Three.js入门指南(张雯莉)-网格 setInterval方法 requestAnimationFrame方法 使用stat.js记录FPS
    系列博文-Three.js入门指南(张雯莉)-照相机
    系列博文-Three.js入门指南(张雯莉)-静态demo和three.js功能概览
    for循环执行效率
    c/c++多维数组动态分配与释放
    C/C++数组指针与指针数组详解
    C/C++语言参数传递----值传递、引用传递、指针传递、指针引用传递
    float类型最大值和最小值
  • 原文地址:https://www.cnblogs.com/vranger/p/3362573.html
Copyright © 2020-2023  润新知