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

 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

原文地址:https://www.cnblogs.com/vranger/p/3362573.html