c++构造函数和析构函数调用规则

原创 2013年08月21日 16:29:57

先看如下程序

/*
	coding by:ygqwan
	in 2013 / 08 / 20
*/
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

class Test
{
public:
	Test(int a):a(a)
	{
		cout << "创建对象 : " << a << endl;
	}
	~Test()
	{
		cout << "销毁对象 : " << a << endl;
	}
	int a;
};
int main()
{
	Test a(1);
	Test b(2);
	Test c(3);
	Test *d = new Test(4);
	Test *e = new Test(5);
	Test *f = new Test(6);
	cout << "--------------------" << endl;
	delete e;
	delete d;
	delete f;
	cout << "++++++++++++++++++++" << endl;

	return 0;	
}



运行结果如下:

创建对象 : 1
创建对象 : 2
创建对象 : 3
创建对象 : 4
创建对象 : 5
创建对象 : 6
--------------------
销毁对象 : 5
销毁对象 : 4
销毁对象 : 6
++++++++++++++++++++
销毁对象 : 3
销毁对象 : 2
销毁对象 : 1
请按任意键继续. . .





可以从运行结果看出, 用new运算符在堆上面开辟的空间跟delete的调用顺序有关

而直接在栈上面开辟的空间的调用规则却是固定的, 还是跟创建的顺序有关,为什么会这样呢?

看了下资料研究了下栈开辟空间的规则后发现是:

栈开辟空间:编译器生成代码在线程栈中移动指针开辟空间

栈销毁空间: 一样的道理, 只是这次移动的顺序是反着移动, 所以就跟生成空间的顺序相反, 那么结果就能够解释了



重点看看在堆上操作空间:

开辟: new一下的时候从全局堆中开辟了空间(这个开辟的算法我不清楚)然后赋值给栈内的指针d, 也就是说编译器一共开辟了两个空间, 空间一是在线程栈中生成一个指针, 空间二是在全剧堆中开辟一个对象空间; 并且栈空间中的指针指向堆空间的地址

销毁: 当delete d;的时候首先是销毁d指向的堆空间的地址里面的数据(怎么销毁的我也不知道), 然后没然后了

当d的作用于到了之后再由编译器自动销毁栈中的指针d;需要注意的是在销毁完d所指向的堆内空间时, d依然是指向那个堆空间的, 但是这个时候用d会出现错误的;

上面的这个错误是很严重的bug:

情况1: d 所指向的空间被系统收回去了, 这个时候d访问的是非法空间, 程序崩溃

情况2: d所指向的空间是别的对象的空间, 那么这个对d的后续操作有影响, 更不得了的是对那个堆内的数据可能照成破坏, 所以bug很严重的, 必须小心呀

情况3:跟2很想,  貌似我不太懂, 就不说了




Java程序员学习C++之构造函数和析构函数调用的时机

今天看书忽然对这个地方有点模糊,尤其是析构函数在调用默认的析构函数和用户自己覆写的析构函数的时候有点意识模糊呢。写段代码总结下   #include       using n...

C++ 派生类构造函数、析构函数调用 [大三TJB_708]

《C++面向对象程序设计》第二版 杜茂康 李昌兵   1 派生类构造函数、析构函数描述 作用和形式 派生类可能有多个基类,也可能包括多个对象成员(指本类中的数据成员,此数据成员为某类定义的对象)。在创...

C++基础:派生类的构造函数与析构函数调用顺序

派生类的构造函数与析构函数调用顺序: 派生类的构造函数的定义形式为: 派生类名::派生类名(参数总表):基类名1(参数表1),基类名2(参数表2),成员对象名1(成员对象参数表1),成员对象名2(...
  • wjxxaut
  • wjxxaut
  • 2016年07月20日 22:34
  • 151

C++中构造函数和析构函数调用的时机

今天看书忽然对这个地方有点模糊,尤其是析构函数在调用默认的析构函数和用户自己覆写的析构函数的时候有点意识模糊呢。写段代码总结下   [cpp] view plaincopy   ...

C++派生类构造函数和析构函数调用顺序

++派生类构造函数调用顺序(详解) 我们来看下面一段代码:   class B1   {   public:   B1(int i) {cout   };   class B2   {...

C++之派生类的构造函数和析构函数调用顺序

派生类的构造函数只负责对派生类新增的成员进行初始化,对所有从基类继承下来的成员,其初始化工作还是由基类的构造函数完成。 派生类的数据成员是由所有基类的数据成员与派生类新增的数据成员共同组成的。如果派生...

【c++继承】继承关系中派生类对象构造函数和析构函数调用顺序

一、派生类对象中基类构造函数和派生类中构造函数调用顺序(WIN7 64位 VS2012) (1)、先执行派生类的构造函数还是先执行基类中的构造函数? 利用下面这段代码进行打印测试 #include ...

C++之析构函数和构造函数调用时间---补充(2)《Effective C++》

今天看书忽然对这个地方有点模糊,尤其是析构函数在调用默认的析构函数和用户自己覆写的析构函数的时候有点意识模糊呢。写段代码总结下[cpp] view plain copy print?#include ...

C++继承中构造函数、析构函数调用顺序及虚函数的动态绑定

昨天面试被问到这些,惭愧的很,居然搞混了,悔恨了一把。决定要彻底搞清楚。也算是有所收获。     首先说说构造函数,大家都知道构造函数里就可以调用成员变量,而继承中子类是把基类的成员变成自己的成员,那...
  • ameyume
  • ameyume
  • 2011年03月29日 13:22
  • 3116

关于构造函数和析构函数调用时的多种情况

关于构造函数和析构函数调用时的多种情况例:有一个类A当这样定义时class AA { public: AA() { cout ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++构造函数和析构函数调用规则
举报原因:
原因补充:

(最多只允许输入30个字)