C++ 虚析构函数
Virtual 关键字起到什么作用
借鉴网友blog, 了解了虚析构函数的作用:
虚析构函数是为了避免内存泄露,而且是当子类中会有指针成员变量时才会使用得到的。
也就说虚析构函数使得在删除指向子类对象的基类指针时可以调用子类的析构函数达到释放子类中堆内存的目的,而防止内存泄露的。
c++中的函数调用默认不适用动态绑定,要触发动态绑定,必须满足两个条件:第一指定为虚函数; 第二通过基类类型的引用或指针调用
Virtual继承及示例和注意事项 --》 注意, 加了virtual的虚虚构函数和不加virtual的析构函数结果不一样哦
virtual可用来定义类函数和应用到虚继承中
注意:
有元函数、构造函数、static静态函数不能用virtual关键字修饰。普通成员函数和析构函数可以用virtual关键字修饰。
#include<stdlib.h> #include<iostream> using namespace std; class GrandFather { public: GrandFather() {} virtual void fun() { cout << "GrandFather call function" << endl; } }; class Father : public GrandFather { public: Father() {} void fun() { cout << "Father call function" << endl; } }; class Son : public Father { public: Son() {} void fun() { cout << "Son call function" << endl; } }; void Print(GrandFather *father) { father->fun(); } int main(int argc, char const *argv[]) { Father *pfather = new Son; pfather->fun(); delete pfather; // GrandFather *grandfather = new Father; // Print(grandfather); return 0; }
多继承的带virtual的虚析构函数
#include <iostream> using namespace std; class GraphFather { private: public: GraphFather(){ cout << "GraphFather structure" << '\n'; }; virtual ~GraphFather(){ cout << "GraphFather deconstruction" << '\n'; }; }; class Father : public GraphFather { private: public: Father(){ cout << "Father structure" << "\n"; }; ~Father(){ cout << "Father deconstruction" << "\n"; }; }; class Son: public Father { private: public: Son(){ cout << "Son structure" << "\n"; }; ~Son(){ cout << "Son Deconstruction" << "\n"; }; }; int main(int argc, char const *argv[]){ Father *gfather = new Son; delete gfather; return 0; };
返回值:
Son call function
先看第一个例子:
#include <iostream> using namespace std; class GraphFather { private: public: GraphFather(){ cout << "GraphFather structure" << '\n'; }; ~GraphFather(){ cout << "GraphFather deconstruction" << '\n'; }; }; class Father : public GraphFather { private: public: Father(){ cout << "Father structure" << "\n"; }; ~Father(){ cout << "Father deconstruction" << "\n"; }; }; class Son: public Father { private: public: Son(){ cout << "Son structure" << "\n"; }; ~Son(){ cout << "Son Deconstruction" << "\n"; }; }; int main(int argc, char const *argv[]){ GraphFather *gfather = new Son; delete gfather; cout << "================" << '\n'; Father *father = new Son; delete father; cout << "================" << '\n'; Son *son = new Son; delete son; cout << "================" << '\n'; return 0; };
返回值:
GraphFather structure Father structure Son structure GraphFather deconstruction -----》 看这里 ================ GraphFather structure Father structure Son structure Father deconstruction ------看这里 GraphFather deconstruction ================ GraphFather structure Father structure Son structure Son Deconstruction -------看这里 Father deconstruction GraphFather deconstruction ================
这样只是理解了执行顺序, 但网友的那篇blog却讲的很好, 记录只是为了更好的理解和回顾
更好的理解virtual的作用, 和使用场景
#include <iostream> using namespace std; class Base { public: Base(){} ~Base() { cout << "Base Destructor." << endl; } private: int a, b; }; class Derive : public Base { public: Derive(){} ~Derive() { cout << "Derive Destructor." << endl; // release memeory if(pI != NULL) { delete pI; } } private: int *pI; }; int main(void) { { Base *pD = new Derive; delete pD; } int i; cin >> i; return 0; }
但结果只执行了基类的析构函数, 在派生类中有没有释放的指针, 这样就造成了内存泄漏
这也是虚析构函数的一个作用
在基类Base中加入虚析构函数virtual ~Base()...
#include <iostream> using namespace std; class Base { public: Base() {} virtual ~Base() { cout << "Base Destructor." << endl; } private: int a, b; }; class Derive : public Base { public: Derive() { pI = new int; } ~Derive() { cout << "Derive Destructor." << endl; // release memeory if (pI != NULL) { delete pI; } } private: int *pI; }; int main(int argc, char const *argv[]) { { Base *pD = new Derive; delete pD; } int i; cin >> i; return 0; }
参考blog1:https://www.cnblogs.com/lit10050528/p/3874703.html
参考blog2: http://www.cnblogs.com/cxq0017/p/6550125.html --》这个blog代码没有delete 对象指针, 需注意
作者:沐禹辰
出处:http://www.cnblogs.com/renfanzi/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
出处:http://www.cnblogs.com/renfanzi/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。