构造函数、析构函数为虚函数的区别
来源:互联网 发布:三个数据库应用系统 编辑:程序博客网 时间:2024/05/21 09:26
关于C++类析构函数为虚函数时,如果是父类的指针用子类来new,如果发生析构时,析构函数是virtual与不是virtual有什么区别。
一、先看第一种最简单的情况吧,教科书上教的,析构函数不是virtual,正常定义一个子类对象
class student { public: int *m_pInt; student() { m_pInt = new int[10]; //1 memset(m_pInt, 0, 10*4); } ~student() { //3 delete []m_pInt; } }; class GradeOneStue:public student { public: int m_iNum; GradeOneStue() { //2 m_iNum = 1; } ~GradeOneStue() { //4 m_iNum = 0; } }; int _tmain(int argc, _TCHAR* argv[]) { GradeOneStue gd; return 0; }
构造函数:先调用父类构造函数,再调用子类构造函数;
再来看看析构时的顺序(教科书上写的是先调用子类的析构函数,在调用父类的,与构造过程相反)
二、析构函数是virtual,正常定义一个子类对象
析构函数最后还是调用了父类的析构(即使是虚函数)。
三、用一个父类指针去new一个子类对象,析构函数不是virtual,构造过程略过
看到只调用了父类的析构函数,此时子类的析构函数没有被调用,此时子类的析构函数中虽然有调用父类析构函数的代码,但是这里直接调用的是父类的析构函数,所以这是如果子类中析构函数有释放资源的代码,这里会造成这部分资源不被释放,有可能造成内存泄露
四、用一个父类指针去new一个子类对象,析构函数是virtual,构造过程略过
由于子类的虚构函数最后会调用父类的析构函数(不管是否为virtual,子类析构函数最后都会调用父类析构函数),所以最终父类的析构函数会得到执行。(这时调用的析构函数相当于pStu->vpTable->析构函数(),这个析构函数是构造时写入的,由于构造时使用子类类型去new,此时虚函数表中析构函数的地址是子类的析构函数地址)
最后的结论:
1、无论父类与子类的析构函数是否是virtual,子类的析构函数都会调用父类的析构函数
2、如果父类与子类的析构函数不为virtual,用一个父类指针指向一个用子类类型new的对象,delete时,直接调用父类的析构函数,这是在编译时刻就决定的。如果子类析构函数中有释放资源的代码,这是会发生资源泄漏。
3、如果父类与子类的析构函数是virtual,用一个父类指针指向一个用子类类型new的对象,delete时,这时由于是通过虚函数表调用析构函数,而虚函数表中的地址是构造时写入的,是子类的析构函数的地址,由于结论第一条,所以子类与父类的析构函数都会得到调用,不会发生资源泄漏。
*************************************************************************************************************
补充:为什么构造函数不能用虚函数
如果有这样两个类:
class A {
public:
A() { a = "A"; f(); }
virtual ~A() {}
virtual f() { cout << a << endl; }
private:
char* a;
};
class B : public A {
public:
B() { b = "B"; }
~B() {}
f() { cout << b << endl; }
private:
char* b;
};
构造函数调用顺序是先调用基类构造函数,即: A(), B()
在A()中调用f(),如果按虚函数调用规则,它应该调用B::f(),但此时B还没构造(B()还没有执行),执行B::f()必然是一个错误。所以在构造函数内部执行时,对象还没有完全构造好,不能按虚函数方式进行调用,构造函数本身不能为虚函数也是相同的原因了。
- 构造函数、析构函数为虚函数的区别
- 构造函数析构函数是否为虚函数
- 构造函数为什么不能为虚函数 & 基类的析构函数为什么要为虚函数
- 构造函数不能为虚函数,析构函数可以为虚函数
- 构造函数不能为虚函数,析构函数可以为虚函数
- 构造函数不能为虚函数,析构函数能并且应该为虚函数
- 为什么构造函数不能声明为虚函数,析构函数可以声明为虚函数
- 构造函数不能为虚函数,析构函数要为虚函数
- 构造函数不能声明为虚函数,析构函数可以声明为虚函数
- 构造函数不能为虚函数,析构函数可为虚函数
- 为什么构造函数不能为虚函数,而析构函数可以为虚函数?
- 为什么构造函数不能为虚函数,而析构函数可以为虚函数
- (1)为什么构造函数的名字用类名?(2)构造函数返回值问题;(3)析构函数和构造函数定义为虚函数;
- 构造函数、析构函数是否要声明为虚函数的问题
- 构造函数、析构函数是否要声明为虚函数的问题(网络转载)
- 构造函数、析构函数是否要声明为虚函数的问题
- 构造函数、析构函数是否要声明为虚函数的问题
- 构造函数不能为虚函数,虚析构函数的作用
- SSH框架的简单搭建步骤
- sql时间查询相关
- fl2440 led驱动移植详细记录
- PHP工作原理
- Solr源码在MyEclipse下的搭建
- 构造函数、析构函数为虚函数的区别
- [转载]如何使用SocketAsyncEventArgs类(How to use the SocketAsyncEventArgs class)
- 求二叉树中节点的最大距离
- 前端面试题
- paper svn
- MATLAB中gradient求数值梯度的命令
- 防止arp攻击
- Ubuntu 12.10 更新源
- 收集了一些Weblogic监控工具