C++静态变量对象的建立和删除,兼论MFC开始运行的起点(全局对象)
看了不少C++书,当讲到静态变量的时候,总是以int成员来举例,是啊,这样很好理解。但是如果这个静态变量是一个对象行不行呢?不仅行,有时候还非常必要,而且别有洞天。
比如:
// .h 文件
class SystemGlobal
{
public:
static ConfigXML* m_pInstance;
}
// .cpp 文件
ConfigXML* SystemGlobal::m_pInstance = new ConfigXML();
SystemGlobal::SystemGlobal(void)
{
}
那么应该何时删除这个对象呢?想了很久,一开始觉得应该是在main()函数里,我这是还是QT程序,不得不改写了main()函数通常的return 方式,变成这样:
MainWidget main_widget;
main_widget.showWidget(); int ret = app.exec();
delete SystemGlobal::m_pInstance;
return ret;
我试了试,程序可以正常退出。反正我试了5遍都没有问题。普通C++程序没有app.exec的困扰,应该更加没有问题。
---------------------------------------------------------
然后我又在网上搜了搜(很难搜到啊),受这个帖子启发:
http://bbs.csdn.net/topics/200006181
改成在拥有静态变量对象的类析构函数里删除它,如下:
SystemGlobal::~SystemGlobal(void)
{
delete SystemGlobal::m_pInstance;
}
同样试了5次,也没有问题。
但是我觉得这种方法不好,因为万一SystemGlobal在整个项目中有多个实例呢,难道销毁一个实例的时候,就必须销毁这个静态对象?这种方法只适合于整个项目就这一个SystemGlobal实例的情况。而且析构函数不允许重载和参数,就显得更加有问题了。
---------------------------------------------------------
最后要提一句,静态变量对象的初始化不仅仅别有洞天,而且实际上是相当重要的,因为它会在main()函数开始前执行,这代表什么?代表在main()函数的第一句语句执行之前,已经执行过这个静态变量对应的类的构造函数了,而构造函数本身可以执行无穷无尽的语句,相当于main()函数只是一个正房,在正房出现前,程序员已经与小三天翻地覆一番后才回来了(真是经典案例!),而且这个小三仍存在于内存之中,与正房并列。
不要奇怪,其实MFC的执行流程就是从CMyApp(继承于CWinApp)的theApp实例生成的过程开始的(注意,theApp不是静态变量对象,但却是一个写在.cpp文件中的全局对象,其实与静态变量对象也没有什么本质的区别,也正因为theApp对象的指针仍需要被获取,但又没有静态变量那么方便,所以微软专门提供了AfxGetApp()全局函数。但是为什么提供这个函数,而不是使用静态变量对象呢?我觉得2个原因,1是静态变量名称又臭又长,2是函数具有更好的封装性,可以做更多的检查乃至偷天换日):
MyApp::MyApp()
{ // 断点2,在括号这行下断点
} MyApp theApp; // 断点1,在这行也下断点 BOOL MyApp::InitInstance()
{
}
// 断点3,手动打开appmodul.cpp文件,然后在_tWinMain的括号处下断点
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,__in LPTSTR lpCmdLine, int nCmdShow)
{
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
执行,通过追踪MFC源代码,可以发现程序首先定位于断点1,按F11追踪,发现会落在断点2。继续按F11,会发现执行CWinApp::CWinApp(LPCTSTR lpszAppName),然后按F10,发现会执行一大堆语句才会返回。可见的确实别有洞天。做完这些事情以后,就开始执行WinMain函数了(断点3),具体可以发现WinMain函数是在appmodul.cpp文件中。
读书笔记,两种效果:1. 在MFC初始化完成后,WinMain被自动调用,两者就相互联系起来了 2. MFC没有也不可能封装WinMain函数(有待进一步阐述)
参考:
http://www.cnblogs.com/zhili/p/mfcanalyze.html
http://www.moon-soft.com/program/bbs/readelite9623.htm
http://www.cnblogs.com/suncoolcat/p/3367627.html
http://www.xuebuyuan.com/2119787.html (彩色贴图,比较清楚)
http://cnmqw.iteye.com/blog/1921782 (精简了代码,非常清楚)
C++静态变量对象的建立和删除,兼论MFC开始运行的起点(全局对象)的更多相关文章
- 全局对象Application的使用,以及如何在任何地方得到Application全局对象
Application和Activity,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个application对象,用来存储系统的一些信息.通常我们是不 ...
- Java 局部变量、实例变量、类变量(静态变量)区别
1. 局部变量: 局部变量是类的方法中的变量: 2. 实例变量: 实例变量也是类中独立于方法之外的变量,不过没有static修饰,也叫 对象变量 3. 类变量(静态变量): 类变量是类中独立于方法之外 ...
- [ 转载 ]Java:成员变量,局部变量,静态变量的区别
精简后方便自己理解. 成员变量 我们研究一个事物: 属性:外在特征:如身高,体重 行为:能做什么:如说话,打球. 在Java语言中,最基本的单位是类(class),类就是用来体现事物的. 属性:类中的 ...
- 1.7Oob 静态变量静态方法
1)静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员 2)如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量. 3)静态方法中不能直接调用非静态方法 ...
- 成员变量(实例变量)&局部变量&静态变量(类变量)的区别
成员变量(实例变量)&局部变量区别: (1)作用域 成员变量:针对整个类有效. 局部变量:只在某个范围内有效.(一般指的就是方法,语句体内) (2)存储位置 成员变量:随着对象的创建而存在,随 ...
- 谈谈java中静态变量与静态方法在有继承关系的两个类中调用
谈谈java中静态变量与静态方法在有继承关系的两个类中调用 学习的中如果遇到不明白或者不清楚的的时候,就是自己做些测试,自己去试试,这次我就做一个关于静态变量和静态方法在有继承关系的两个类中的问题测试 ...
- java 静态变量&静态方法
1. 静态变量是static修饰的成员变量(类变量),若无static修饰,则是实例变量.静态变量是一种全局变量,它属于某个类,不属于某个对象实例,是在各对象实例间共存. 访问静态变量直接通过类名 ...
- JavaScript中hoisting(悬置/置顶解析/预解析) 实例解释,全局对象,隐含的全局概念
JavaScript中hoisting(悬置/置顶解析/预解析) 实例解释,全局对象,隐含的全局概念 <html> <body> <script type="t ...
- JavaScript 全局对象
全局属性和函数可用于所有内建的 JavaScript 对象. 顶层函数(全局函数) 函数 描述 decodeURI() 解码某个编码的 URI. decodeURIComponent() 解码一个编码 ...
随机推荐
- (转)CSS行高——line-height
原文地址:http://www.cnblogs.com/dolphinX/p/3236686.html 初入前端的时候觉得CSS知道display.position.float就可以在布局上游刃有余了 ...
- 20160331javaweb之JSP include 指令&&九大隐式对象
3.零散知识 (1)jsp映射 <servlet> <servlet-name>index</servlet-name> <jsp-file>/inde ...
- Chrome资源加载被Cancel的问题
好个表久没写文章了. 做为一个砖业的砖工只能天天搬砖做些没有营养没有技术难度的活儿. 最近折腾个网站.发现一个很奇怪的问题- 各种图片的请求被取消了状态为Canceled. 顿时Chrome变成一个更 ...
- Android开发环境搭建(2015年8月更新)
1. 下载和安装Android SDK Android的官方站点是http://www.android.com: 登录https://developer.android.com/intl/zh-cn ...
- linux字符过滤
1 案例一:取eth0的IP地址 方法一:通过cut方法过滤 [root@baiguin ~]# ifconfig eth0|grep "inet addr:"|cut -d & ...
- Maximum Product Subarray动态规划思想
该题即是昨天没有做出来的题目,想了很久,想出了一个普通的做法,提交发现超时了.思想是新建一个数组,保存每个元素与后面的元素相乘后得到的最大值,然后再在该数组中选出最大的值,返回.[笨死 发现行不通后决 ...
- 自动构建工具Ant的使用-笔记
第一:什么是Ant? Apache Ant是一个基于Java的生成工具.据最初的创始人James Duncan Davidson的介绍,这个工具的名称是another neat tool(另一个整洁的 ...
- python模块与包
模块是包括python定义和声明的文件.文件名=模块名+".py".模块名保存在全局变量__name__中. 1.模块中的执行语句,只是在导入时执行一次.这些语句通常用于初始化模块 ...
- 10.08_逛逛OSC
(1)每天逛逛OSC是我的习惯了. JNative.JACOB.Shrinkwrap API? .Lua.WSO2 Identity Server .JBoss Forge.Bugzilla.Cou ...
- 04_过滤器Filter_03_多个Filter的执行顺序
[Filter链] *在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为一个Filter链. *web服务器根据Filter在web.xml中的注册顺序,决定先调用哪个Fi ...