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() 解码一个编码 ...
随机推荐
- 四种方式写按钮点击事件和Android 中常用的布局
1.匿名内部类的方式 2.创建一个类实现onClickListener,实现onClick方法,设置控件点击时传一个类的对象 3.让当前类实现onClickListener,设置控件点击事件时传递一个 ...
- div置于页面底部
一直对于页面置底有一些困惑,下面这个例子不知道能不能解决 <!DOCTYPE html> <html lang="en"> <head> < ...
- Android 抽屉效果
昨天在用“酷我音乐”听歌的时候注意到了界面右上角的四角方块,当我点击这个方块的时候会从屏幕的左边弹出新的界面而把原来的界面挤到左边,是显示了一小部分. 于是,我便在网上查询了一下相关的文章,现将这种效 ...
- MVC小系列(十四)【MVC+ZTree大数据异步树加载】
ZTree是一个jquery的树插件可以异步加载 第一步定义一个标准的接口(指的是与ztree默认的数据元素保持一致) /// <summary> /// ZTree数据结构 /// &l ...
- boa服务器问题日志
1. 某一次在登录boa服务器的时候,不知哪里的问题,无法登录「192.168.1.0-192.168.3.255」网段的设备,但是公司IP网段的机器都可以用.最终发现,问题出现在自己的PC添加了浏览 ...
- MySQL存储引擎,优化,事务
1唯一约束unique和主键key的区别? 1.什么是数据的存储引擎? 存储引擎就是如何存储数据.如何为存储的数据建立索引和如何更新.查询数据等技术的实现方法.因为在关系数据库中数 ...
- absolute之实现居中的三种方式
居中思想可以由很多方式实现,这篇文章采用absolute实现:由传统方式开始到absolute独立使用方式 方式一:传统方式,父容器relateive,子元素absolute,然后left:50%,再 ...
- HTTP协议-标签简介
这个系列的文章要讨论的是如何通过ASP.net服务器端技术来优化客户端缓存策略,而且让这种策略变得可配置和可扩展.我们要了解的知识从HTTP协议中相关属性对客户端缓存的影响,到ASP.NET如何控制这 ...
- jquery禁用a标签,jquery禁用按钮click点击
jquery禁用a标签方法1 $(document).ready(function () { $("a").each(function () { var textValue = $ ...
- 如何判断list中是否包含某个元素
在python中可以通过in和not in关键字来判读一个list中是否包含一个元素: str = ['s','i','m','o','n'] if 'e' in str: print("e ...